30b7c233c4ed5096be244e71208e0085e29a691d
[yaffs-website] / vendor / drupal-composer / drupal-scaffold / src / PrestissimoFileFetcher.php
1 <?php
2
3 namespace DrupalComposer\DrupalScaffold;
4
5 use Composer\Util\RemoteFilesystem;
6 use Composer\Config;
7 use Composer\IO\IOInterface;
8 use Hirak\Prestissimo\CopyRequest;
9 use Hirak\Prestissimo\CurlMulti;
10
11 /**
12  * Extends the default FileFetcher and uses hirak/prestissimo for parallel
13  * downloads.
14  */
15 class PrestissimoFileFetcher extends FileFetcher {
16
17   /**
18    * @var \Composer\Config
19    */
20   protected $config;
21
22   /**
23    * Constructs this PrestissimoFileFetcher object.
24    */
25   public function __construct(RemoteFilesystem $remoteFilesystem, $source, IOInterface $io, $progress = TRUE, Config $config) {
26     parent::__construct($remoteFilesystem, $source, $io, $progress);
27     $this->config = $config;
28   }
29
30   /**
31    * {@inheritdoc}
32    */
33   public function fetch($version, $destination, $override) {
34     if (class_exists(CurlMulti::class)) {
35       $this->fetchWithPrestissimo($version, $destination, $override);
36       return;
37     }
38     parent::fetch($version, $destination, $override);
39   }
40
41   /**
42    * Fetch files in parallel.
43    */
44   protected function fetchWithPrestissimo($version, $destination, $override) {
45     $requests = [];
46
47     foreach ($this->filenames as $sourceFilename => $filename) {
48       $target = "$destination/$filename";
49       if ($override || !file_exists($target)) {
50         $url = $this->getUri($sourceFilename, $version);
51         $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename));
52         $requests[] = new CopyRequest($url, $target, FALSE, $this->io, $this->config);
53       }
54     }
55
56     $successCnt = $failureCnt = 0;
57     $errors = [];
58     $totalCnt = count($requests);
59     if ($totalCnt == 0) {
60       return;
61     }
62
63     $multi = new CurlMulti();
64     $multi->setRequests($requests);
65     do {
66       $multi->setupEventLoop();
67       $multi->wait();
68       $result = $multi->getFinishedResults();
69       $successCnt += $result['successCnt'];
70       $failureCnt += $result['failureCnt'];
71       if (isset($result['errors'])) {
72         $errors += $result['errors'];
73       }
74       if ($this->progress) {
75         foreach ($result['urls'] as $url) {
76           $this->io->writeError("  - Downloading <comment>$successCnt</comment>/<comment>$totalCnt</comment>: <info>$url</info>", TRUE);
77         }
78       }
79     } while ($multi->remain());
80
81     $urls = array_keys($errors);
82     if ($urls) {
83       throw new \Exception('Failed to download ' . implode(", ", $urls));
84     }
85   }
86
87 }