generated from yiisoft/package-template
/
FilesExtractor.php
173 lines (146 loc) · 4.84 KB
/
FilesExtractor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<?php
declare(strict_types=1);
namespace Yiisoft\Config;
use ErrorException;
use Yiisoft\Config\Composer\Options;
use function array_merge;
use function glob;
use function is_file;
use function sprintf;
use function substr;
/**
* @internal
*/
final class FilesExtractor
{
public function __construct(
private ConfigPaths $paths,
private MergePlan $mergePlan,
private DataModifiers $dataModifiers,
private string $environment,
) {
}
/**
* Extracts group configuration data from files.
*
* @param string $group The group name.
*
* @throws ErrorException If an error occurred during the extract.
*
* @psalm-return array<string, Context>
*/
public function extract(string $group): array
{
$environment = $this->prepareEnvironment($group);
$result = $this->process(Options::DEFAULT_ENVIRONMENT, $group, $this->mergePlan->getGroup($group));
if ($environment !== Options::DEFAULT_ENVIRONMENT) {
$result = array_merge(
$result,
$this->process(
$environment,
$group,
$this->mergePlan->getGroup($group, $environment)
)
);
}
return $result;
}
/**
* Checks whether the group exists in the merge plan.
*
* @param string $group The group name.
*
* @return bool Whether the group exists in the merge plan.
*/
public function hasGroup(string $group): bool
{
return $this->mergePlan->hasGroup($group, $this->environment) || (
$this->environment !== Options::DEFAULT_ENVIRONMENT &&
$this->mergePlan->hasGroup($group, Options::DEFAULT_ENVIRONMENT)
);
}
/**
* @psalm-param array<string, string[]> $data
*
* @throws ErrorException If an error occurred during the process.
*
* @psalm-return array<string, Context>
*/
private function process(string $environment, string $group, array $data): array
{
$result = [];
foreach ($data as $package => $items) {
$layer = $this->detectLayer($environment, $package);
if ($this->dataModifiers->shouldRemoveGroupFromVendor($package, $group, $layer)) {
continue;
}
foreach ($items as $item) {
if (Options::isVariable($item)) {
$result[$item] = new Context($group, $package, $layer, $item, true);
continue;
}
$isOptional = Options::isOptional($item);
if ($isOptional) {
$item = substr($item, 1);
}
$filePath = $this->paths->absolute($item, $package);
$files = Options::containsWildcard($item) ? glob($filePath) : [$filePath];
foreach ($files as $file) {
if (is_file($file)) {
$result[$file] = new Context($group, $package, $layer, $file, false);
} elseif (!$isOptional) {
$this->throwException(sprintf('The "%s" file does not found.', $file));
}
}
}
}
return $result;
}
/**
* Calculates the layer for the context.
*
* @param string $environment The environment name.
* @param string $package The package name.
*
* @return int The layer for the context.
*/
private function detectLayer(string $environment, string $package): int
{
if ($package !== Options::ROOT_PACKAGE_NAME) {
return $package === Options::VENDOR_OVERRIDE_PACKAGE_NAME ? Context::VENDOR_OVERRIDE : Context::VENDOR;
}
if ($environment === Options::DEFAULT_ENVIRONMENT) {
return Context::APPLICATION;
}
return Context::ENVIRONMENT;
}
/**
* Checks the group name and returns actual environment name.
*
* @param string $group The group name.
*
* @throws ErrorException If the group does not exist.
*
* @return string The actual environment name.
*/
private function prepareEnvironment(string $group): string
{
if (!$this->mergePlan->hasGroup($group, $this->environment)) {
if (
$this->environment === Options::DEFAULT_ENVIRONMENT ||
!$this->mergePlan->hasGroup($group, Options::DEFAULT_ENVIRONMENT)
) {
$this->throwException(sprintf('The "%s" configuration group does not exist.', $group));
}
return Options::DEFAULT_ENVIRONMENT;
}
return $this->environment;
}
/**
* @throws ErrorException
*/
private function throwException(string $message): void
{
throw new ErrorException($message, 0, E_USER_ERROR);
}
}