Passed
Push — master ( a495f4...f57b36 )
by Koldo
02:34
created

ConfigAggregator   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 91.8%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 16
eloc 63
c 5
b 0
f 1
dl 0
loc 109
ccs 56
cts 61
cp 0.918
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A mergeConfig() 0 18 3
A canNotCreateCacheDirectory() 0 9 4
A checkCacheConfig() 0 7 1
A __construct() 0 13 3
A parse() 0 14 1
A getMergedConfig() 0 3 1
A cacheConfig() 0 15 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\SymfonyConfigTranslator\Container\Config;
6
7
use Antidot\SymfonyConfigTranslator\AliasTranslator;
8
use Antidot\SymfonyConfigTranslator\ConditionalTranslator;
9
use Antidot\SymfonyConfigTranslator\FactoryTranslator;
10
use Antidot\SymfonyConfigTranslator\InvokableTranslator;
11
use Antidot\SymfonyConfigTranslator\TagTranslator;
12
use DateTimeImmutable;
13
use RuntimeException;
14
use Laminas\ConfigAggregator\ConfigAggregator as BaseAggregator;
15
16
use function array_replace_recursive;
17
use function date;
18
use function file_exists;
19
use function file_put_contents;
20
use function get_class;
21
use function is_string;
22
use function json_decode;
23
use function json_encode;
24
use function sprintf;
25
use function str_replace;
26
use function var_export;
27
28
class ConfigAggregator extends BaseAggregator
29
{
30
    public const CACHE_TEMPLATE = <<< 'EOT'
31
<?php
32
/**
33
 * This configuration cache file was generated by %s
34
 * at %s
35
 */
36
return %s;
37
38
EOT;
39
40
    private array $config;
41
42 4
    public function __construct(array $providers = [], $cachedConfigFile = null, array $postProcessors = [])
43
    {
44 4
        if (is_string($cachedConfigFile)) {
45 2
            if (file_exists($cachedConfigFile)) {
46 1
                $this->config = include $cachedConfigFile;
47 1
                return;
48
            }
49 2
            parent::__construct($providers);
50 2
            $this->checkCacheConfig($cachedConfigFile);
51
        } else {
52 2
            parent::__construct($providers, $cachedConfigFile, $postProcessors);
53 2
            $config = $this->parse(parent::getMergedConfig());
54 2
            $this->config = $this->mergeConfig($config);
55
        }
56 4
    }
57
58 4
    public function getMergedConfig(): array
59
    {
60 4
        return $this->config;
61
    }
62
63 2
    private function checkCacheConfig(string $cachedConfigFile): void
64
    {
65 2
        $this->config = $this->mergeConfig(parent::getMergedConfig());
66
67 2
        $this->cacheConfig(
68 2
            $this->config,
69
            $cachedConfigFile
70
        );
71 2
    }
72
73 2
    private function parse(array $defaultConfig): array
74
    {
75 2
        $config = array_replace_recursive(
76 2
            (new TagTranslator())->process($defaultConfig['services']),
77 2
            (new FactoryTranslator())->process($defaultConfig),
78 2
            (new ConditionalTranslator())->process($defaultConfig),
79 2
            (new InvokableTranslator())->process($defaultConfig['services']),
80 2
            (new AliasTranslator())->process($defaultConfig['services']),
81 2
            $defaultConfig
82 2
        ) ?? [];
83 2
        $config = array_replace_recursive($config, $config['dependencies'] ?? []);
84 2
        unset($config['dependencies']);
85
86 2
        return $config ?? [];
87
    }
88
89 2
    private function cacheConfig(array $config, string $cachedConfigFile): void
90
    {
91 2
        if (true === $config['config_cache_enabled']) {
92 2
            if ($this->canNotCreateCacheDirectory($cachedConfigFile)) {
93
                throw new RuntimeException(sprintf(
94
                    'Cache file "%s" was not created, because cannot create cache directory',
95
                    $cachedConfigFile
96
                ));
97
            }
98
99 2
            file_put_contents($cachedConfigFile, sprintf(
100 2
                self::CACHE_TEMPLATE,
101 2
                get_class($this),
102 2
                date('c'),
103 2
                var_export($config, true)
104
            ));
105
        }
106 2
    }
107
108 4
    private function mergeConfig(array $config): array
109
    {
110 4
        if (false === empty($config['parameters'])) {
111 1
            $config['parameters'] = json_decode(
112 1
                str_replace(
113 1
                    '%date%',
114 1
                    (new DateTimeImmutable())->format('Y-m-d'),
115 1
                    json_encode($config['parameters']) ?: ''
116
                ),
117 1
                true,
118 1
                16,
119 1
                JSON_THROW_ON_ERROR
120
            );
121 1
            $config = array_replace_recursive($config, $config['parameters'] ?? []);
122 1
            unset($config['parameters']);
123
        }
124
125 4
        return $config ?? [];
126
    }
127
128 2
    private function canNotCreateCacheDirectory(string $cachedConfigFile): bool
129
    {
130 2
        $concurrentDirectory = dirname($cachedConfigFile);
131 2
        if (file_exists($cachedConfigFile) || is_dir($concurrentDirectory)) {
132 2
            return false;
133
        }
134
135
        return !mkdir($concurrentDirectory, 0755, true)
136
            && !is_dir($concurrentDirectory);
137
    }
138
}
139