1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
namespace Shopware\Psh\Config; |
4
|
|
|
|
5
|
|
|
use function array_merge; |
6
|
|
|
use function array_pop; |
7
|
|
|
use function array_shift; |
8
|
|
|
use function count; |
9
|
|
|
use function dirname; |
10
|
|
|
use function glob; |
11
|
|
|
use function is_dir; |
12
|
|
|
|
13
|
|
|
class ConfigFactory |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @var ConfigMerger |
17
|
|
|
*/ |
18
|
|
|
private $configMerger; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var ConfigFileFinder |
22
|
|
|
*/ |
23
|
|
|
private $configFileFinder; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var ConfigFileLoader[] |
27
|
|
|
*/ |
28
|
|
|
private $configLoaders; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var ConfigLogger |
32
|
|
|
*/ |
33
|
|
|
private $configLogger; |
34
|
|
|
|
35
|
|
|
public function __construct( |
36
|
|
|
ConfigMerger $configMerger, |
37
|
|
|
ConfigFileFinder $configFileFinder, |
38
|
|
|
ConfigLogger $configLogger, |
39
|
|
|
array $configLoaders |
40
|
|
|
) { |
41
|
|
|
$this->configMerger = $configMerger; |
42
|
|
|
$this->configFileFinder = $configFileFinder; |
43
|
|
|
$this->configLoaders = $configLoaders; |
44
|
|
|
$this->configLogger = $configLogger; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @return Config[] |
49
|
|
|
*/ |
50
|
|
|
public function gatherConfigs( |
51
|
|
|
array $configFiles, |
52
|
|
|
array $overwrittenConsts |
53
|
|
|
): array { |
54
|
|
|
$configs = []; |
55
|
|
|
$additionalConfigs = [[]]; |
56
|
|
|
|
57
|
|
|
foreach ($configFiles as $configFile) { |
58
|
|
|
foreach ($this->configLoaders as $configLoader) { |
59
|
|
|
if (!$configLoader->isSupported($configFile)) { |
60
|
|
|
continue; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
$config = $configLoader |
64
|
|
|
->load($configFile, $overwrittenConsts); |
65
|
|
|
|
66
|
|
|
$additionalConfigs[] = $this |
67
|
|
|
->loadImports($config, dirname($configFile), $overwrittenConsts); |
68
|
|
|
|
69
|
|
|
$configs[] = $config; |
70
|
|
|
} |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
if (!$configs) { |
|
|
|
|
74
|
|
|
return []; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$config = $this->configMerger->mergeOverride(...$configs); |
|
|
|
|
78
|
|
|
|
79
|
|
|
return array_merge([$config], ...array_merge(...$additionalConfigs)); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
private function loadImports( |
83
|
|
|
Config $config, |
84
|
|
|
string $fromPath, |
85
|
|
|
array $overwrittenConsts |
86
|
|
|
): array { |
87
|
|
|
$additionalConfigs = []; |
88
|
|
|
|
89
|
|
|
foreach ($config->getImports() as $importPath) { |
90
|
|
|
$foundSomething = false; |
91
|
|
|
foreach (glob($fromPath . '/' . $importPath) as $foundOccurrence) { |
92
|
|
|
if (!is_dir($foundOccurrence)) { |
93
|
|
|
continue; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
$foundConfigFiles = $this->configFileFinder |
97
|
|
|
->discoverConfigInDirectory($foundOccurrence); |
98
|
|
|
|
99
|
|
|
if (count($foundConfigFiles) === 0) { |
100
|
|
|
continue; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
$foundSomething = true; |
104
|
|
|
$this->configLogger->importConfigFiles($importPath, ...$foundConfigFiles); |
|
|
|
|
105
|
|
|
$additionalConfigs[] = $this |
106
|
|
|
->gatherConfigs($foundConfigFiles, $overwrittenConsts); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
if (!$foundSomething) { |
110
|
|
|
$this->configLogger->notifyImportNotFound($importPath); |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
return $additionalConfigs; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* @param Config[] $configs |
119
|
|
|
*/ |
120
|
|
|
public function mergeConfigs(array $configs): Config |
121
|
|
|
{ |
122
|
|
|
$mainConfig = array_shift($configs); |
123
|
|
|
|
124
|
|
|
while (count($configs) !== 0) { |
125
|
|
|
$mainConfig = $this->configMerger->mergeImport($mainConfig, array_pop($configs)); |
|
|
|
|
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
return $mainConfig; |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.