5 * Contains Drupal\Console\Command\Shared\ProjectDownloadTrait.
8 namespace Drupal\Console\Command\Shared;
10 use Drupal\Console\Zippy\Adapter\TarGzGNUTarForWindowsAdapter;
11 use Drupal\Console\Zippy\FileStrategy\TarGzFileForWindowsStrategy;
12 use Alchemy\Zippy\Zippy;
13 use Alchemy\Zippy\Adapter\AdapterContainer;
14 use Symfony\Component\Filesystem\Filesystem;
17 * Class ProjectDownloadTrait
19 * @package Drupal\Console\Command
21 trait ProjectDownloadTrait
23 public function modulesQuestion()
27 $modules = $this->extensionManager->discoverModules()
33 $moduleName = $this->getIo()->choiceNoList(
34 $this->trans('commands.module.install.questions.module'),
40 if (empty($moduleName) && is_numeric($moduleName)) {
44 $moduleList[] = $moduleName;
46 if (array_search($moduleName, $moduleList, true) >= 0) {
47 unset($modules[array_search($moduleName, $modules)]);
54 public function modulesUninstallQuestion()
58 $modules = $this->extensionManager->discoverModules()
65 $moduleName = $this->getIo()->choiceNoList(
66 $this->trans('commands.module.uninstall.questions.module'),
72 if (empty($moduleName) || is_numeric($modules)) {
76 $moduleList[] = $moduleName;
82 private function downloadModules($modules, $latest, $path = null, $resultList = [])
91 drupal_static_reset('system_rebuild_module_data');
93 $missingModules = $this->validator->getMissingModules($modules);
96 if ($missingModules) {
99 $this->trans('commands.module.install.messages.getting-missing-modules'),
100 implode(', ', $missingModules)
103 foreach ($missingModules as $missingModule) {
104 $version = $this->releasesQuestion($missingModule, $latest);
106 $this->downloadProject($missingModule, $version, 'module', $path);
108 $invalidModules[] = $missingModule;
109 unset($modules[array_search($missingModule, $modules)]);
111 $this->extensionManager->discoverModules();
115 $unInstalledModules = $this->validator->getUninstalledModules($modules);
117 $dependencies = $this->calculateDependencies($unInstalledModules);
120 'invalid' => array_unique(array_merge($resultList['invalid'], $invalidModules)),
121 'uninstalled' => array_unique(array_merge($resultList['uninstalled'], $unInstalledModules)),
122 'dependencies' => array_unique(array_merge($resultList['dependencies'], $dependencies))
125 if (!$dependencies) {
129 return $this->downloadModules($dependencies, $latest, $path, $resultList);
132 protected function calculateDependencies($modules)
134 $this->site->loadLegacyFile('/core/modules/system/system.module');
135 $moduleList = system_rebuild_module_data();
139 foreach ($modules as $moduleName) {
140 $module = $moduleList[$moduleName];
142 $dependencies = array_unique(
145 $this->validator->getUninstalledModules(
146 array_keys($module->requires)?:[]
152 return array_diff($dependencies, $modules);
163 public function downloadProject($project, $version, $type, $path = null)
165 $commandKey = str_replace(':', '.', $this->getName());
167 $this->getIo()->comment(
169 $this->trans('commands.'.$commandKey.'.messages.downloading'),
176 $destination = $this->drupalApi->downloadProjectRelease(
182 $path = $this->getExtractPath($type);
185 $projectPath = sprintf(
191 if (!file_exists($projectPath)) {
192 if (!mkdir($projectPath, 0777, true)) {
193 $this->getIo()->error(
195 $this->trans('commands.'.$commandKey.'.messages.error-creating-folder'),
203 $zippy = Zippy::load();
204 if (PHP_OS === "WIN32" || PHP_OS === "WINNT") {
205 $container = AdapterContainer::load();
206 $container['Drupal\\Console\\Zippy\\Adapter\\TarGzGNUTarForWindowsAdapter'] = function ($container) {
207 return TarGzGNUTarForWindowsAdapter::newInstance(
208 $container['executable-finder'],
209 $container['resource-manager'],
210 $container['gnu-tar.inflator'],
211 $container['gnu-tar.deflator']
214 $zippy->addStrategy(new TarGzFileForWindowsStrategy($container));
216 $archive = $zippy->open($destination);
217 if ($type == 'core') {
218 $archive->extract(getenv('MSYSTEM') ? null : $projectPath);
219 } elseif (getenv('MSYSTEM')) {
220 $current_dir = getcwd();
221 $temp_dir = sys_get_temp_dir();
224 $fileSystem = new Filesystem();
225 $fileSystem->rename($temp_dir . '/' . $project, $projectPath . '/' . $project);
228 $archive->extract($projectPath);
231 unlink($destination);
233 if ($type != 'core') {
234 $this->getIo()->success(
237 'commands.' . $commandKey . '.messages.downloaded'
241 sprintf('%s/%s', $projectPath, $project)
245 } catch (\Exception $e) {
246 $this->getIo()->error($e->getMessage());
255 * @param string $project
256 * @param bool $latest
257 * @param bool $stable
260 public function releasesQuestion($project, $latest = false, $stable = false)
262 $commandKey = str_replace(':', '.', $this->getName());
264 $this->getIo()->comment(
266 $this->trans('commands.'.$commandKey.'.messages.getting-releases'),
267 implode(',', [$project])
271 $releases = $this->drupalApi->getProjectReleases($project, $latest?1:15, $stable);
274 $this->getIo()->error(
276 $this->trans('commands.'.$commandKey.'.messages.no-releases'),
277 implode(',', [$project])
288 $version = $this->getIo()->choice(
289 $this->trans('commands.'.$commandKey.'.messages.select-release'),
300 private function getExtractPath($type)
304 return 'modules/contrib';
315 * check if a modules repo is in composer.json
316 * check if the repo is setted and matchs the one in config.yml
318 * @param object $config
321 private function repositoryAlreadySet($config, $repo)
323 if (!$config->repositories) {
326 if (in_array($repo, $config->repositories)) {