PluginDownloader::downloadPlugins()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Paysera\PhpStormHelper\Service;
5
6
use RuntimeException;
7
use Alchemy\Zippy\Zippy;
8
use GuzzleHttp\ClientInterface;
9
use Symfony\Component\Filesystem\Filesystem;
10
11
class PluginDownloader
12
{
13
    private $directoryResolver;
14
    private $zippy;
15
    private $client;
16
    private $filesystem;
17
18 8
    public function __construct(
19
        DirectoryResolver $directoryResolver,
20
        Zippy $zippy,
21
        ClientInterface $client,
22
        Filesystem $filesystem
23
    ) {
24 8
        $this->directoryResolver = $directoryResolver;
25 8
        $this->zippy = $zippy;
26 8
        $this->client = $client;
27 8
        $this->filesystem = $filesystem;
28 8
    }
29
30 2
    public function downloadPlugins(array $plugins)
31
    {
32 2
        $pluginDirectory = $this->directoryResolver->getPluginDirectory();
33
34 2
        foreach ($plugins as $pluginUrl) {
35 2
            $this->ensurePluginInstalled($pluginDirectory, $pluginUrl);
36
        }
37 2
    }
38
39 2
    private function ensurePluginInstalled(string $pluginDirectory, string $pluginUrl)
40
    {
41 2
        $path = parse_url($pluginUrl, PHP_URL_PATH);
42 2
        $filename = basename($path);
43 2
        $parts = explode('.', $filename);
44 2
        if ($parts < 2) {
45
            throw new RuntimeException(sprintf('Unexpected filename (%s) for plugin %s', $filename, $pluginUrl));
46
        }
47 2
        $extension = $parts[count($parts) - 1];
48 2
        if (!in_array($extension, ['jar', 'zip'], true)) {
49
            throw new RuntimeException(sprintf('Unexpected extension (%s) for plugin %s', $extension, $pluginUrl));
50
        }
51
52 2
        $pluginName = $this->resolvePluginName($extension, $filename);
53 2
        $pluginFullPath = $pluginDirectory . '/' . $pluginName;
54 2
        if (file_exists($pluginFullPath)) {
55
            return;
56
        }
57
58 2
        $this->downloadPlugin($pluginUrl, $extension, $pluginFullPath);
59 2
    }
60
61 2
    private function resolvePluginName(string $extension, string $filename): string
62
    {
63 2
        if ($extension !== 'zip') {
64 1
            return $filename;
65
        }
66
67 1
        $parts = explode('-', $filename);
68 1
        if (count($parts) < 2) {
69
            throw new RuntimeException(sprintf('Unexpected plugin filename %s', $filename));
70
        }
71 1
        unset($parts[count($parts) - 1]);
72 1
        $name = implode('-', $parts);
73
74 1
        return str_replace('_', ' ', $name);
75
    }
76
77 2
    private function downloadPlugin(string $pluginUrl, string $extension, string $pluginFullPath)
78
    {
79 2
        $response = $this->client->request('GET', $pluginUrl);
80 2
        if ($response->getStatusCode() !== 200) {
81
            throw new RuntimeException(sprintf('Unexpected status code %s', $response->getStatusCode()));
82
        }
83
84 2
        if ($extension !== 'zip') {
85 1
            $this->filesystem->dumpFile($pluginFullPath, $response->getBody()->getContents());
86 1
            return;
87
        }
88
89 1
        $zipFullPath = $pluginFullPath . '.zip';
90 1
        $this->filesystem->dumpFile($zipFullPath, $response->getBody()->getContents());
91 1
        $this->zippy->open($zipFullPath)->extract(dirname($pluginFullPath));
92 1
        $this->filesystem->remove($zipFullPath);
93 1
    }
94
}
95