Completed
Push — master ( c1dd30...d92f40 )
by Jan Philipp
11s
created

YamlConfigFileLoader::extractData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 3
1
<?php declare(strict_types=1);
2
3
4
namespace Shopware\Psh\Config;
5
6
use Symfony\Component\Yaml\Parser;
7
8
/**
9
 * Load the config data from a yaml file
10
 */
11
class YamlConfigFileLoader implements ConfigLoader
12
{
13
    const KEY_HEADER = 'header';
14
15
    const KEY_DYNAMIC_VARIABLES = 'dynamic';
16
17
    const KEY_CONST_VARIABLES = 'const';
18
19
    const KEY_COMMAND_PATHS = 'paths';
20
21
    const KEY_ENVIRONMENTS = 'environments';
22
23
    const KEY_TEMPLATES = 'templates';
24
25
    /**
26
     * @var Parser
27
     */
28
    private $yamlReader;
29
30
    /**
31
     * @var ConfigBuilder
32
     */
33
    private $configBuilder;
34
35
    /**
36
     * @var string
37
     */
38
    private $applicationRootDirectory;
39
40
    /**
41
     * @param Parser $yamlReader
42
     * @param ConfigBuilder $configBuilder
43
     * @param string $applicationRootDirectory
44
     */
45
    public function __construct(Parser $yamlReader, ConfigBuilder $configBuilder, string $applicationRootDirectory)
46
    {
47
        $this->yamlReader = $yamlReader;
48
        $this->configBuilder = $configBuilder;
49
        $this->applicationRootDirectory = $applicationRootDirectory;
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55
    public function isSupported(string $file): bool
56
    {
57
        return in_array(pathinfo($file, PATHINFO_EXTENSION), ['yaml', 'yml', 'dist', 'override'], true);
58
    }
59
60
    /**
61
     * @inheritdoc
62
     */
63
    public function load(string $file, array $params): Config
64
    {
65
        $contents = $this->loadFileContents($file);
66
        $rawConfigData = $this->parseFileContents($contents);
67
68
        $this->configBuilder->start();
69
70
        $this->configBuilder
71
            ->setHeader(
72
                $this->extractData(self::KEY_HEADER, $rawConfigData, '')
0 ignored issues
show
Documentation introduced by
'' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
73
            );
74
75
        $this->setConfigData($file, $rawConfigData);
76
77
        $environments = $this->extractData(self::KEY_ENVIRONMENTS, $rawConfigData, []);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
78
79
        foreach ($environments as $name => $data) {
80
            $this->configBuilder->start($name);
81
            $this->setConfigData($file, $data);
82
        }
83
84
        return $this->configBuilder
85
            ->create($params);
86
    }
87
88
    /**
89
     * @param string $file
90
     * @param array $rawConfigData
91
     */
92
    private function setConfigData(string $file, array $rawConfigData)
93
    {
94
        $this->configBuilder->setCommandPaths(
95
            $this->extractCommandPaths($file, $rawConfigData)
96
        );
97
98
        $this->configBuilder->setDynamicVariables(
99
            $this->extractData(self::KEY_DYNAMIC_VARIABLES, $rawConfigData, [])
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
100
        );
101
102
        $this->configBuilder->setConstants(
103
            $this->extractData(self::KEY_CONST_VARIABLES, $rawConfigData, [])
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
104
        );
105
106
        $this->configBuilder->setTemplates(
107
            $this->extractTemplates($file, $rawConfigData)
108
        );
109
    }
110
111
    /**
112
     * @param string $key
113
     * @param array $rawConfig
114
     * @param bool $default
115
     * @return mixed|null
116
     */
117
    private function extractData(string $key, array $rawConfig, $default = false)
118
    {
119
        if (!array_key_exists($key, $rawConfig)) {
120
            return $default;
121
        }
122
123
        return $rawConfig[$key];
124
    }
125
126
    /**
127
     * @param string $file
128
     * @return string
129
     */
130
    private function loadFileContents(string $file): string
131
    {
132
        return file_get_contents($file);
133
    }
134
135
    /**
136
     * @param string $contents
137
     * @return array
138
     */
139
    private function parseFileContents(string $contents): array
140
    {
141
        return $this->yamlReader->parse($contents);
142
    }
143
144
    /**
145
     * @param string $file
146
     * @param $rawConfigData
147
     * @return array
148
     */
149
    private function extractCommandPaths(string $file, array $rawConfigData): array
150
    {
151
        $paths = $this->extractData(self::KEY_COMMAND_PATHS, $rawConfigData, []);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
152
153
        return array_map(function ($path) use ($file) {
154
            return $this->fixPath($path, $file);
155
        }, $paths);
156
    }
157
158
    /**
159
     * @param string $file
160
     * @param array $rawConfigData
161
     * @return array
162
     */
163
    private function extractTemplates(string $file, array $rawConfigData): array
164
    {
165
        $templates = $this->extractData(self::KEY_TEMPLATES, $rawConfigData, []);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
166
167
        return array_map(function ($template) use ($file) {
168
            $template['source'] = $this->fixPath($template['source'], $file);
169
            $template['destination'] = $this->makeAbsolutePath($file, $template['destination']);
170
171
            return $template;
172
        }, $templates);
173
    }
174
175
    /**
176
     * @param string $absoluteOrRelativePath
177
     * @param string $baseFile
178
     * @return string
179
     * @throws \InvalidArgumentException
180
     */
181
    private function fixPath(string $absoluteOrRelativePath, string $baseFile): string
182
    {
183
        $possiblyValidFiles = [
184
            $this->applicationRootDirectory . '/' . $absoluteOrRelativePath,
185
            $this->makeAbsolutePath($baseFile, $absoluteOrRelativePath),
186
            $absoluteOrRelativePath,
187
        ];
188
189
        foreach ($possiblyValidFiles as $file) {
190
            if (file_exists($file)) {
191
                return $file;
192
            }
193
        }
194
195
        throw new \InvalidArgumentException(sprintf(
196
            'Unable to find a file referenced by "%s", tried: %s',
197
            $absoluteOrRelativePath,
198
            print_r($possiblyValidFiles, true)
199
        ));
200
    }
201
202
    /**
203
     * @param string $baseFile
204
     * @param string $path
205
     * @return string
206
     */
207
    private function makeAbsolutePath(string $baseFile, string $path): string
208
    {
209
        return pathinfo($baseFile, PATHINFO_DIRNAME) . '/' . $path;
210
    }
211
}
212