Passed
Push — master ( 880edd...e0ae4e )
by Dorian
01:56
created

Kernel::getConfigAbsoluteFilePath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php declare(strict_types=1);
2
3
namespace App;
4
5
use App\Domain\Content;
6
use App\Domain\PathPart;
7
use App\UI\UserInterface;
8
use Symfony\Component\Filesystem\Filesystem;
9
use Symfony\Component\Yaml\Yaml;
10
11
final class Kernel
12
{
13
    public const DEFAULT_CONFIG = 'config/app.yml';
14
15
    /** @var string */
16
    private $projectDir;
17
18
    /**
19
     * @param string $projectDir
20
     */
21
    public function __construct(string $projectDir)
22
    {
23
        $this->projectDir = rtrim($projectDir, DIRECTORY_SEPARATOR);
24
    }
25
26
    /**
27
     * @param string $configFilePath
28
     * @param \App\UI\UserInterface $ui
29
     *
30
     * @throws \RuntimeException
31
     * @throws \Symfony\Component\Filesystem\Exception\IOException
32
     * @throws \Symfony\Component\Yaml\Exception\ParseException
33
     */
34
    public function __invoke($configFilePath, UserInterface $ui): void
35
    {
36
        $config = (array) Yaml::parseFile($this->getConfigAbsoluteFilePath($configFilePath));
37
        $rootPathPart = $this->getRootPathPart($config['path_part'] ?? []);
38
39
        foreach ((array) $config['sources'] as $sources) {
40
            foreach ((array) $sources as $sourceClassName => $sourceData) {
41
42
                /** @var \App\Domain\Source $source */
43
                $source = new $sourceClassName($ui, $sourceData['config'] ?? []);
44
45
                // Add the root path part to the contents' path
46
                $contents = $source->getContents()
47
                    ->map(function (Content $content) use ($rootPathPart) {
48
                        $content->getPath()->add($rootPathPart);
49
50
                        return $content;
51
                    });
52
53
                foreach ((array) $sourceData['downloaders'] as $downloaders) {
54
                    foreach ((array) $downloaders as $downloaderClassName => $downloaderData) {
55
56
                        /** @var \App\Domain\Downloader $downloader */
57
                        $downloader = new $downloaderClassName($ui, $downloaderData['config'] ?? []);
58
                        $downloader->synchronizeContents(clone $contents, $rootPathPart);
59
                    }
60
                }
61
            }
62
        }
63
    }
64
65
    /**
66
     * @param array $config
67
     *
68
     * @return \App\Domain\PathPart
69
     *
70
     * @throws \RuntimeException
71
     * @throws \Symfony\Component\Filesystem\Exception\IOException
72
     */
73
    private function getRootPathPart(array $config): PathPart
74
    {
75
        $config['substitutions'] = ['%project_root%' => $this->projectDir] + ($config['substitutions'] ?? []);
76
        $rootPathPart = new PathPart($config);
77
78
        // Try to create the root directory... 'cause if it fails, nothing will work.
79
        (new Filesystem())->mkdir($rootPathPart->getPath());
80
81
        return $rootPathPart;
82
    }
83
84
    /**
85
     * @param string $configFilePath
86
     *
87
     * @return string
88
     * @throws \RuntimeException
89
     */
90
    private function getConfigAbsoluteFilePath(string $configFilePath): string
91
    {
92
        if (DIRECTORY_SEPARATOR === $configFilePath{0}) {
93
            return $configFilePath;
94
        }
95
96
        return $this->projectDir.DIRECTORY_SEPARATOR.$configFilePath;
97
    }
98
}
99