Passed
Push — master ( 24286a...4f8819 )
by Dorian
01:51
created

Kernel::getAllConfigFilesPaths()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
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\Finder\Finder;
10
use Symfony\Component\Yaml\Yaml;
11
12
final class Kernel
13
{
14
    /** @var string */
15
    private $projectDir;
16
17
    /** @var string */
18
    private $configDir;
19
20
    /**
21
     * @param string $projectDir
22
     */
23
    public function __construct(string $projectDir)
24
    {
25
        $this->projectDir = rtrim($projectDir, DIRECTORY_SEPARATOR);
26
        $this->configDir = $projectDir.DIRECTORY_SEPARATOR.'config';
27
    }
28
29
    /**
30
     * @param \App\UI\UserInterface $ui
31
     * @param string $singleConfigFilePath
32
     *
33
     * @throws \RuntimeException
34
     * @throws \Symfony\Component\Filesystem\Exception\IOException
35
     * @throws \Symfony\Component\Yaml\Exception\ParseException
36
     */
37
    public function __invoke(UserInterface $ui, $singleConfigFilePath = ''): void
38
    {
39
        $configFilesPaths = !empty($singleConfigFilePath)
40
            ? [$this->getConfigAbsoluteFilePath($singleConfigFilePath)]
41
            : $this->getAllConfigFilesPaths();
42
43
        foreach ($configFilesPaths as $configFilePath) {
44
            $ui->write(
45
                sprintf(
46
                    'Processing configuration file "<info>%s</info>"... ',
47
                    $this->getConfigRelativeFilePath($configFilePath)
48
                )
49
            );
50
            $config = (array) Yaml::parseFile($configFilePath);
51
            $config['enabled'] = $config['enabled'] ?? true;
52
53
            if (!$config['enabled']) {
54
                $ui->writeln('<info>Skipped.</info>'.PHP_EOL);
55
                continue;
56
            }
57
            $ui->writeln(PHP_EOL);
58
59
            $rootPathPart = $this->getRootPathPart($config['path_part'] ?? []);
60
61
            foreach ((array) $config['sources'] as $sources) {
62
                foreach ((array) $sources as $sourceClassName => $sourceData) {
63
64
                    /** @var \App\Domain\Source $source */
65
                    $source = new $sourceClassName($ui, $sourceData['config'] ?? []);
66
67
                    // Add the root path part to the contents' path
68
                    $contents = $source->getContents()
69
                        ->map(function (Content $content) use ($rootPathPart) {
70
                            $content->getPath()->add($rootPathPart);
71
72
                            return $content;
73
                        });
74
75
                    foreach ((array) $sourceData['downloaders'] as $downloaders) {
76
                        foreach ((array) $downloaders as $downloaderClassName => $downloaderData) {
77
78
                            /** @var \App\Domain\Downloader $downloader */
79
                            $downloader = new $downloaderClassName($ui, $downloaderData['config'] ?? []);
80
                            $downloader->synchronizeContents(clone $contents, $rootPathPart);
81
                        }
82
                    }
83
                }
84
            }
85
        }
86
    }
87
88
    /**
89
     * @return array
90
     */
91
    private function getAllConfigFilesPaths(): array
92
    {
93
        $paths = [];
94
95
        foreach ((new Finder())->in($this->configDir)->files()->sortByName()->name('*.yml')->getIterator() as $file) {
96
            $paths[] = $file->getRealPath();
97
        }
98
99
        return $paths;
100
    }
101
102
    /**
103
     * @param array $config
104
     *
105
     * @return \App\Domain\PathPart
106
     *
107
     * @throws \RuntimeException
108
     * @throws \Symfony\Component\Filesystem\Exception\IOException
109
     */
110
    private function getRootPathPart(array $config): PathPart
111
    {
112
        $config['substitutions'] = ['%project_root%' => $this->projectDir] + ($config['substitutions'] ?? []);
113
        $rootPathPart = new PathPart($config);
114
115
        // Try to create the root directory... 'cause if it fails, nothing will work.
116
        (new Filesystem())->mkdir($rootPathPart->getPath());
117
118
        return $rootPathPart;
119
    }
120
121
    /**
122
     * @param string $configFilePath
123
     *
124
     * @return string
125
     */
126
    private function getConfigRelativeFilePath(string $configFilePath): string
127
    {
128
        return (string) str_replace($this->projectDir.DIRECTORY_SEPARATOR, '', $configFilePath);
129
    }
130
131
    /**
132
     * @param string $configFilePath
133
     *
134
     * @return string
135
     * @throws \RuntimeException
136
     */
137
    private function getConfigAbsoluteFilePath(string $configFilePath): string
138
    {
139
        if (DIRECTORY_SEPARATOR === $configFilePath{0}) {
140
            return $configFilePath;
141
        }
142
143
        return $this->projectDir.DIRECTORY_SEPARATOR.$configFilePath;
144
    }
145
}
146