Passed
Pull Request — master (#74)
by Dmitriy
15:05
created

Config::replaceMarkers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
ccs 0
cts 4
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A Config::getOutputPath() 0 3 2
1
<?php
2
3
namespace Yiisoft\Composer\Config\Config;
4
5
use Yiisoft\Arrays\ArrayHelper;
6
use Yiisoft\Composer\Config\Builder;
7
use Yiisoft\Composer\Config\ContentWriter;
8
use Yiisoft\Composer\Config\Reader\ReaderFactory;
9
use Yiisoft\Composer\Config\Util\Helper;
10
use Yiisoft\Composer\Config\Util\PathHelper;
11
12
/**
13
 * Config class represents output configuration file.
14
 */
15
class Config
16
{
17
    /**
18
     * @var string config name
19
     */
20
    private string $name;
21
22
    /**
23
     * @var array sources - paths to config source files
24
     */
25
    private array $sources = [];
26
27
    /**
28
     * @var array config value
29
     */
30
    protected array $values = [];
31
32
    protected Builder $builder;
33
34
    protected ContentWriter $contentWriter;
35
36
    public function __construct(Builder $builder, string $name)
37
    {
38 1
        $this->builder = $builder;
39
        $this->name = $name;
40 1
        $this->contentWriter = new ContentWriter();
41 1
    }
42 1
43 1
    public function clone(Builder $builder): self
44
    {
45
        $config = new Config($builder, $this->name);
46
        $config->sources = $this->sources;
47
        $config->values = $this->values;
48
49
        return $config;
50
    }
51
52
    public function getValues(): array
53
    {
54
        return $this->values;
55
    }
56
57
    public function load(array $paths = []): self
58
    {
59
        $this->sources = $this->loadFiles($paths);
60
61
        return $this;
62
    }
63
64
    private function loadFiles(array $paths): array
65
    {
66
        switch (count($paths)) {
67
            case 0:
68
                return [];
69
            case 1:
70
                return [$this->loadFile(reset($paths))];
71
        }
72
73
        $configs = [];
74
        foreach ($paths as $path) {
75
            $cs = $this->loadFiles($this->glob($path));
76
            foreach ($cs as $config) {
77
                if (!empty($config)) {
78
                    $configs[] = $config;
79
                }
80
            }
81
        }
82
83
        return $configs;
84
    }
85
86
    private function glob(string $path): array
87
    {
88
        if (strpos($path, '*') === false) {
89
            return [$path];
90
        }
91
92
        return glob($path);
0 ignored issues
show
Bug Best Practice introduced by
The expression return glob($path) could return the type false which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
93
    }
94
95
    /**
96
     * Reads config file.
97
     *
98
     * @param string $path
99
     * @return array configuration read from file
100
     */
101
    protected function loadFile(string $path): array
102
    {
103
        $reader = ReaderFactory::get($this->builder, $path);
104
105
        return $reader->read($path);
106
    }
107
108
    /**
109
     * Merges given configs and writes at given name.
110
     *
111
     * @return Config
112
     */
113
    public function build(): self
114
    {
115
        $this->values = $this->calcValues($this->sources);
116
117
        return $this;
118
    }
119
120
    public function write(): self
121
    {
122
        $this->writeFile($this->getOutputPath(), $this->values);
123
124
        return $this;
125
    }
126
127
    protected function calcValues(array $sources): array
128
    {
129
        return ArrayHelper::merge(...$sources);
130
    }
131
132
    protected function writeFile(string $path, array $data): void
133
    {
134
        $depth = $this->findDepth();
135
        $baseDir = $depth > 0 ? "dirname(__DIR__, $depth)" : '__DIR__';
136
137
        $envs = $this->envsRequired() ? "\$_ENV = array_merge((array) require __DIR__ . '/envs.php', \$_ENV);" : '';
138
        $constants = $this->constantsRequired() ? $this->builder->getConfig('constants')->buildRequires() : '';
139
        $params = $this->paramsRequired() ? "\$params = (array) require __DIR__ . '/params.php';" : '';
140
        $variables = Helper::exportVar($data);
141
142
        $content = <<<PHP
143
<?php
144
145
\$baseDir = {$baseDir};
146
147
{$envs}
148
149
{$constants}
150
151
{$params}
152
153
return {$variables};
154
PHP;
155
156
        $this->contentWriter->write($path, $content . "\n");
157
    }
158
159
    protected function envsRequired(): bool
160
    {
161
        return true;
162
    }
163
164
    protected function constantsRequired(): bool
165
    {
166
        return true;
167
    }
168
169
    protected function paramsRequired(): bool
170
    {
171
        return true;
172
    }
173
174
    private function findDepth(): int
175
    {
176
        $outDir = PathHelper::realpath(dirname($this->getOutputPath()));
177
        $diff = substr($outDir, strlen(PathHelper::realpath($this->getBaseDir())));
178
179
        return substr_count($diff, '/');
180
    }
181
182
    private function getBaseDir(): string
183
    {
184
        return $this->builder->getBaseDir();
185
    }
186
187
    private function getOutputPath(string $name = null): string
188
    {
189
        return $this->builder->getOutputPath($name ?: $this->name);
190
    }
191
}
192