Completed
Pull Request — master (#1)
by Dorian
02:14
created

Downloader::shouldDownload()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
c 0
b 0
f 0
rs 8.439
cc 5
eloc 16
nc 3
nop 2
1
<?php declare(strict_types=1);
2
3
namespace App\Domain;
4
5
use App\Filesystem\FilesystemManager;
6
use App\UI\UserInterface;
7
use Symfony\Component\Filesystem\Filesystem;
8
use Symfony\Component\Yaml\Yaml;
9
10
abstract class Downloader extends FilesystemManager
11
{
12
    /** @var array */
13
    protected $config;
14
15
    /**
16
     * {@inheritdoc}
17
     * @param array $config
18
     *
19
     * @throws \Symfony\Component\Yaml\Exception\ParseException
20
     */
21
    public function __construct(UserInterface $ui, array $config = [])
22
    {
23
        parent::__construct($ui);
24
25
        if (!empty($configFilePath = $this->getConfigFilePath())) {
26
            $config += (array) Yaml::parseFile($configFilePath);
27
        }
28
29
        $this->config = $config;
30
    }
31
32
    /**
33
     * {@inheritdoc}
34
     * @throws \RuntimeException
35
     * @throws \Symfony\Component\Filesystem\Exception\IOException
36
     */
37
    public function synchronizeContents(Contents $contents, PathPart $rootPathPart): void
38
    {
39
        if ($contents->isEmpty()) {
40
            return;
41
        }
42
43
        $downloaderPathPart = new PathPart($this->config['path_part'] ?? []);
44
        $downloadPath = new Path([$rootPathPart, $downloaderPathPart]);
45
46
        // Try to create the downloads directory... 'cause if it fails, nothing will work.
47
        (new Filesystem())->mkdir((string) $downloadPath);
48
49
        // Add the downloader path part and get a collection of downloads
50
        $downloads = $this->createDownloadsCollection();
51
        foreach ($contents as $content) {
52
            $content->getPath()->add($downloaderPathPart);
53
54
            foreach ($this->extractDownloads($content) as $download) {
55
                $downloads->add($download);
56
            }
57
        }
58
59
        $this->cleanFilesystem($downloads, $downloadPath);
60
61
        $downloads = $this->filterAlreadyDownloaded($downloads);
62
63
        if ($this->shouldDownload($downloads, $downloadPath)) {
64
            $this->download($downloads, $downloadPath);
65
        }
66
    }
67
68
    /**
69
     * @return string
70
     */
71
    abstract protected function getConfigFilePath(): string;
72
73
    /**
74
     * @return Downloads
75
     */
76
    abstract protected function createDownloadsCollection(): Downloads;
77
78
    /**
79
     * @param \App\Domain\Downloads $downloads
80
     *
81
     * @return \App\Domain\Downloads
82
     */
83
    abstract protected function filterAlreadyDownloaded(Downloads $downloads): Downloads;
84
85
    /**
86
     * @param \App\Domain\Content $content
87
     *
88
     * @return \App\Domain\Downloads
89
     */
90
    abstract protected function extractDownloads(Content $content): Downloads;
91
92
    /**
93
     * @param \App\Domain\Downloads $downloads
94
     * @param \App\Domain\Path $downloadPath
95
     *
96
     * @throws \RuntimeException
97
     */
98
    abstract protected function download(Downloads $downloads, Path $downloadPath): void;
99
100
    /**
101
     * @param \App\Domain\Downloads $downloads
102
     * @param \App\Domain\Path $downloadPath
103
     *
104
     * @return bool
105
     */
106
    private function shouldDownload(Downloads $downloads, Path $downloadPath): bool
107
    {
108
        $this->ui->writeln(sprintf('Downloading files with <info>%s</info>... '.PHP_EOL, static::class));
109
110
        if ($downloads->isEmpty()) {
111
            $this->ui->writeln($this->ui->indent().'<comment>Nothing to download.</comment>'.PHP_EOL);
112
113
            return false;
114
        }
115
116
        $this->ui->writeln(
117
            sprintf(
118
                '%sThe script is about to download <question> %s </question> files into <info>%s</info>. '.PHP_EOL,
119
                $this->ui->indent(),
120
                $downloads->count(),
121
                (string) $downloadPath
122
            )
123
        );
124
125
        $this->ui->write($this->ui->indent());
126
        if ($this->skip($this->ui) || !$this->ui->confirm()) {
127
            $this->ui->writeln(($this->ui->isDryRun() ? '' : PHP_EOL).'<info>Done.</info>'.PHP_EOL);
128
129
            return false;
130
        }
131
132
        return true;
133
    }
134
}
135