88b5cff6e82632af8ef9f3130f9bdce62a744fbb
[yaffs-website] / vendor / drupal / console / src / Command / Shared / ProjectDownloadTrait.php
1 <?php
2
3 /**
4  * @file
5  * Contains Drupal\Console\Command\Shared\ProjectDownloadTrait.
6  */
7
8 namespace Drupal\Console\Command\Shared;
9
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;
15
16 /**
17  * Class ProjectDownloadTrait
18  *
19  * @package Drupal\Console\Command
20  */
21 trait ProjectDownloadTrait
22 {
23     public function modulesQuestion()
24     {
25         $moduleList = [];
26
27         $modules = $this->extensionManager->discoverModules()
28             ->showUninstalled()
29             ->showNoCore()
30             ->getList(true);
31
32         while (true) {
33             $moduleName = $this->getIo()->choiceNoList(
34                 $this->trans('commands.module.install.questions.module'),
35                 $modules,
36                 '',
37                 true
38             );
39
40             if (empty($moduleName) && is_numeric($moduleName)) {
41                 break;
42             }
43
44             $moduleList[] = $moduleName;
45
46             if (array_search($moduleName, $moduleList, true) >= 0) {
47                 unset($modules[array_search($moduleName, $modules)]);
48             }
49         }
50
51         return $moduleList;
52     }
53
54     public function modulesUninstallQuestion()
55     {
56         $moduleList = [];
57
58         $modules = $this->extensionManager->discoverModules()
59             ->showInstalled()
60             ->showNoCore()
61             ->showCore()
62             ->getList(true);
63
64         while (true) {
65             $moduleName = $this->getIo()->choiceNoList(
66                 $this->trans('commands.module.uninstall.questions.module'),
67                 $modules,
68                 '',
69                 true
70             );
71
72             if (empty($moduleName) || is_numeric($modules)) {
73                 break;
74             }
75
76             $moduleList[] = $moduleName;
77         }
78
79         return $moduleList;
80     }
81
82     private function downloadModules($modules, $latest, $path = null, $resultList = [])
83     {
84         if (!$resultList) {
85             $resultList = [
86               'invalid' => [],
87               'uninstalled' => [],
88               'dependencies' => []
89             ];
90         }
91         drupal_static_reset('system_rebuild_module_data');
92
93         $missingModules = $this->validator->getMissingModules($modules);
94
95         $invalidModules = [];
96         if ($missingModules) {
97             $this->getIo()->info(
98                 sprintf(
99                     $this->trans('commands.module.install.messages.getting-missing-modules'),
100                     implode(', ', $missingModules)
101                 )
102             );
103             foreach ($missingModules as $missingModule) {
104                 $version = $this->releasesQuestion($missingModule, $latest);
105                 if ($version) {
106                     $this->downloadProject($missingModule, $version, 'module', $path);
107                 } else {
108                     $invalidModules[] = $missingModule;
109                     unset($modules[array_search($missingModule, $modules)]);
110                 }
111                 $this->extensionManager->discoverModules();
112             }
113         }
114
115         $unInstalledModules = $this->validator->getUninstalledModules($modules);
116
117         $dependencies = $this->calculateDependencies($unInstalledModules);
118
119         $resultList = [
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))
123         ];
124
125         if (!$dependencies) {
126             return $resultList;
127         }
128
129         return $this->downloadModules($dependencies, $latest, $path, $resultList);
130     }
131
132     protected function calculateDependencies($modules)
133     {
134         $this->site->loadLegacyFile('/core/modules/system/system.module');
135         $moduleList = system_rebuild_module_data();
136
137         $dependencies = [];
138
139         foreach ($modules as $moduleName) {
140             $module = $moduleList[$moduleName];
141
142             $dependencies = array_unique(
143                 array_merge(
144                     $dependencies,
145                     $this->validator->getUninstalledModules(
146                         array_keys($module->requires)?:[]
147                     )
148                 )
149             );
150         }
151
152         return array_diff($dependencies, $modules);
153     }
154
155     /**
156      * @param $project
157      * @param $version
158      * @param $type
159      * @param $path
160      *
161      * @return string
162      */
163     public function downloadProject($project, $version, $type, $path = null)
164     {
165         $commandKey = str_replace(':', '.', $this->getName());
166
167         $this->getIo()->comment(
168             sprintf(
169                 $this->trans('commands.'.$commandKey.'.messages.downloading'),
170                 $project,
171                 $version
172             )
173         );
174
175         try {
176             $destination = $this->drupalApi->downloadProjectRelease(
177                 $project,
178                 $version
179             );
180
181             if (!$path) {
182                 $path = $this->getExtractPath($type);
183             }
184
185             $projectPath = sprintf(
186                 '%s/%s',
187                 $this->appRoot,
188                 $path
189             );
190
191             if (!file_exists($projectPath)) {
192                 if (!mkdir($projectPath, 0777, true)) {
193                     $this->getIo()->error(
194                         sprintf(
195                             $this->trans('commands.'.$commandKey.'.messages.error-creating-folder'),
196                             $projectPath
197                         )
198                     );
199                     return null;
200                 }
201             }
202
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']
212                     );
213                 };
214                 $zippy->addStrategy(new TarGzFileForWindowsStrategy($container));
215             }
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();
222                 chdir($temp_dir);
223                 $archive->extract();
224                 $fileSystem = new Filesystem();
225                 $fileSystem->rename($temp_dir . '/' . $project, $projectPath . '/' . $project);
226                 chdir($current_dir);
227             } else {
228                 $archive->extract($projectPath);
229             }
230
231             unlink($destination);
232
233             if ($type != 'core') {
234                 $this->getIo()->success(
235                     sprintf(
236                         $this->trans(
237                             'commands.' . $commandKey . '.messages.downloaded'
238                         ),
239                         $project,
240                         $version,
241                         sprintf('%s/%s', $projectPath, $project)
242                     )
243                 );
244             }
245         } catch (\Exception $e) {
246             $this->getIo()->error($e->getMessage());
247
248             return null;
249         }
250
251         return $projectPath;
252     }
253
254     /**
255      * @param string                                 $project
256      * @param bool                                   $latest
257      * @param bool                                   $stable
258      * @return string
259      */
260     public function releasesQuestion($project, $latest = false, $stable = false)
261     {
262         $commandKey = str_replace(':', '.', $this->getName());
263
264         $this->getIo()->comment(
265             sprintf(
266                 $this->trans('commands.'.$commandKey.'.messages.getting-releases'),
267                 implode(',', [$project])
268             )
269         );
270
271         $releases = $this->drupalApi->getProjectReleases($project, $latest?1:15, $stable);
272
273         if (!$releases) {
274             $this->getIo()->error(
275                 sprintf(
276                     $this->trans('commands.'.$commandKey.'.messages.no-releases'),
277                     implode(',', [$project])
278                 )
279             );
280
281             return null;
282         }
283
284         if ($latest) {
285             return $releases[0];
286         }
287
288         $version = $this->getIo()->choice(
289             $this->trans('commands.'.$commandKey.'.messages.select-release'),
290             $releases
291         );
292
293         return $version;
294     }
295
296     /**
297      * @param $type
298      * @return string
299      */
300     private function getExtractPath($type)
301     {
302         switch ($type) {
303         case 'module':
304             return 'modules/contrib';
305         case 'theme':
306             return 'themes';
307         case 'profile':
308             return 'profiles';
309         case 'core':
310             return '';
311         }
312     }
313
314     /**
315      * check if a modules repo is in composer.json
316      * check if the repo is setted and matchs the one in config.yml
317      *
318      * @param  object $config
319      * @return boolean
320      */
321     private function repositoryAlreadySet($config, $repo)
322     {
323         if (!$config->repositories) {
324             return false;
325         } else {
326             if (in_array($repo, $config->repositories)) {
327                 return true;
328             } else {
329                 return false;
330             }
331         }
332     }
333 }