5 * Contains Drupal\Console\Command\Shared\ProjectDownloadTrait.
8 namespace Drupal\Console\Command\Shared;
10 use Drupal\Console\Core\Style\DrupalStyle;
11 use Drupal\Console\Zippy\Adapter\TarGzGNUTarForWindowsAdapter;
12 use Drupal\Console\Zippy\FileStrategy\TarGzFileForWindowsStrategy;
13 use Alchemy\Zippy\Zippy;
14 use Alchemy\Zippy\Adapter\AdapterContainer;
15 use Symfony\Component\Filesystem\Filesystem;
18 * Class ProjectDownloadTrait
20 * @package Drupal\Console\Command
22 trait ProjectDownloadTrait
24 public function modulesQuestion(DrupalStyle $io)
28 $modules = $this->extensionManager->discoverModules()
34 $moduleName = $io->choiceNoList(
35 $this->trans('commands.module.install.questions.module'),
41 if (empty($moduleName)) {
45 $moduleList[] = $moduleName;
47 if (array_search($moduleName, $moduleList, true) >= 0) {
48 unset($modules[array_search($moduleName, $modules)]);
55 public function modulesUninstallQuestion(DrupalStyle $io)
59 $modules = $this->extensionManager->discoverModules()
66 $moduleName = $io->choiceNoList(
67 $this->trans('commands.module.uninstall.questions.module'),
73 if (empty($moduleName)) {
77 $moduleList[] = $moduleName;
83 private function downloadModules(DrupalStyle $io, $modules, $latest, $path = null, $resultList = [])
92 drupal_static_reset('system_rebuild_module_data');
94 $missingModules = $this->validator->getMissingModules($modules);
97 if ($missingModules) {
100 $this->trans('commands.module.install.messages.getting-missing-modules'),
101 implode(', ', $missingModules)
104 foreach ($missingModules as $missingModule) {
105 $version = $this->releasesQuestion($io, $missingModule, $latest);
107 $this->downloadProject($io, $missingModule, $version, 'module', $path);
109 $invalidModules[] = $missingModule;
110 unset($modules[array_search($missingModule, $modules)]);
112 $this->extensionManager->discoverModules();
116 $unInstalledModules = $this->validator->getUninstalledModules($modules);
118 $dependencies = $this->calculateDependencies($unInstalledModules);
121 'invalid' => array_unique(array_merge($resultList['invalid'], $invalidModules)),
122 'uninstalled' => array_unique(array_merge($resultList['uninstalled'], $unInstalledModules)),
123 'dependencies' => array_unique(array_merge($resultList['dependencies'], $dependencies))
126 if (!$dependencies) {
130 return $this->downloadModules($io, $dependencies, $latest, $path, $resultList);
133 protected function calculateDependencies($modules)
135 $this->site->loadLegacyFile('/core/modules/system/system.module');
136 $moduleList = system_rebuild_module_data();
140 foreach ($modules as $moduleName) {
141 $module = $moduleList[$moduleName];
143 $dependencies = array_unique(
146 $this->validator->getUninstalledModules(
147 array_keys($module->requires)?:[]
153 return array_diff($dependencies, $modules);
157 * @param \Drupal\Console\Core\Style\DrupalStyle $io
165 public function downloadProject(DrupalStyle $io, $project, $version, $type, $path = null)
167 $commandKey = str_replace(':', '.', $this->getName());
171 $this->trans('commands.'.$commandKey.'.messages.downloading'),
178 $destination = $this->drupalApi->downloadProjectRelease(
184 $path = $this->getExtractPath($type);
187 $projectPath = sprintf(
193 if (!file_exists($projectPath)) {
194 if (!mkdir($projectPath, 0777, true)) {
197 $this->trans('commands.'.$commandKey.'.messages.error-creating-folder'),
205 $zippy = Zippy::load();
206 if (PHP_OS === "WIN32" || PHP_OS === "WINNT") {
207 $container = AdapterContainer::load();
208 $container['Drupal\\Console\\Zippy\\Adapter\\TarGzGNUTarForWindowsAdapter'] = function ($container) {
209 return TarGzGNUTarForWindowsAdapter::newInstance(
210 $container['executable-finder'],
211 $container['resource-manager'],
212 $container['gnu-tar.inflator'],
213 $container['gnu-tar.deflator']
216 $zippy->addStrategy(new TarGzFileForWindowsStrategy($container));
218 $archive = $zippy->open($destination);
219 if ($type == 'core') {
220 $archive->extract(getenv('MSYSTEM') ? null : $projectPath);
221 } elseif (getenv('MSYSTEM')) {
222 $current_dir = getcwd();
223 $temp_dir = sys_get_temp_dir();
226 $fileSystem = new Filesystem();
227 $fileSystem->rename($temp_dir . '/' . $project, $projectPath . '/' . $project);
230 $archive->extract($projectPath);
233 unlink($destination);
235 if ($type != 'core') {
239 'commands.' . $commandKey . '.messages.downloaded'
243 sprintf('%s/%s', $projectPath, $project)
247 } catch (\Exception $e) {
248 $io->error($e->getMessage());
257 * @param \Drupal\Console\Core\Style\DrupalStyle $io
258 * @param string $project
259 * @param bool $latest
260 * @param bool $stable
263 public function releasesQuestion(DrupalStyle $io, $project, $latest = false, $stable = false)
265 $commandKey = str_replace(':', '.', $this->getName());
269 $this->trans('commands.'.$commandKey.'.messages.getting-releases'),
270 implode(',', [$project])
274 $releases = $this->drupalApi->getProjectReleases($project, $latest?1:15, $stable);
279 $this->trans('commands.'.$commandKey.'.messages.no-releases'),
280 implode(',', [$project])
291 $version = $io->choice(
292 $this->trans('commands.'.$commandKey.'.messages.select-release'),
303 private function getExtractPath($type)
307 return 'modules/contrib';
318 * check if a modules repo is in composer.json
319 * check if the repo is setted and matchs the one in config.yml
321 * @param object $config
324 private function repositoryAlreadySet($config, $repo)
326 if (!$config->repositories) {
329 if (in_array($repo, $config->repositories)) {