Test Failed
Push — master ( d2e85c...a495f4 )
by Koldo
02:17
created

ConfigAggregator   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Test Coverage

Coverage 87.88%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 17
eloc 68
c 5
b 0
f 1
dl 0
loc 117
ccs 58
cts 66
cp 0.8788
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getMergedConfig() 0 3 1
A __construct() 0 12 3
A checkCacheConfig() 0 7 1
A mergeConfig() 0 23 4
A canNotCreateCacheDirectory() 0 13 4
A parse() 0 14 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
            $this->config = $this->mergeConfig(parent::getMergedConfig());
54
        }
55 4
    }
56
57 4
    public function getMergedConfig(): array
58
    {
59 4
        return $this->config;
60
    }
61
62 2
    private function checkCacheConfig(string $cachedConfigFile): void
63
    {
64 2
        $this->config = $this->mergeConfig(parent::getMergedConfig());
65
66 2
        $this->cacheConfig(
67 2
            $this->config,
68
            $cachedConfigFile
69
        );
70 2
    }
71
72 1
    private function parse(array $defaultConfig): array
73
    {
74 1
        $config = array_replace_recursive(
75 1
            $defaultConfig,
76 1
            (new TagTranslator())->process($defaultConfig['services']),
77 1
            (new FactoryTranslator())->process($defaultConfig),
78 1
            (new ConditionalTranslator())->process($defaultConfig),
79 1
            (new AliasTranslator())->process($defaultConfig['services']),
80 1
            (new InvokableTranslator())->process($defaultConfig['services'])
81 1
        ) ?? [];
82 1
        $config = array_merge($config, $config['dependencies'] ?? []);
83 1
        unset($config['dependencies']);
84
85 1
        return $config;
86
    }
87
88 2
    private function cacheConfig(array $config, string $cachedConfigFile): void
89
    {
90 2
        if (true === $config['config_cache_enabled']) {
91 2
            if ($this->canNotCreateCacheDirectory($cachedConfigFile)) {
92
                throw new RuntimeException(sprintf(
93
                    'Cache file "%s" was not created, because cannot create cache directory',
94
                    $cachedConfigFile
95
                ));
96
            }
97
98 2
            file_put_contents($cachedConfigFile, sprintf(
99 2
                self::CACHE_TEMPLATE,
100 2
                get_class($this),
101 2
                date('c'),
102 2
                var_export($config, true)
103
            ));
104
        }
105 2
    }
106
107 4
    private function mergeConfig(array $config): array
108
    {
109 4
        if (false === empty($config['parameters'])) {
110 1
            $config['parameters'] = json_decode(
111 1
                str_replace(
112 1
                    '%date%',
113 1
                    (new DateTimeImmutable())->format('Y-m-d'),
114 1
                    json_encode($config['parameters']) ?: ''
115
                ),
116 1
                true,
117 1
                16,
118 1
                JSON_THROW_ON_ERROR
119
            );
120 1
            $config = array_replace_recursive($config, $config['parameters'] ?? []);
121 1
            unset($config['parameters']);
122
        }
123
124 4
        if (false === empty($config['services'])) {
125 1
            $config = $this->parse($config);
126 1
            unset($config['services']);
127
        }
128
129 4
        return $config;
130
    }
131
132 2
    private function canNotCreateCacheDirectory(string $cachedConfigFile): bool
133
    {
134 2
        $concurrentDirectory = dirname($cachedConfigFile);
135 2
        if (file_exists($cachedConfigFile) || is_dir($concurrentDirectory)) {
136 2
            return false;
137
        }
138
139
        return !mkdir(
140
            $concurrentDirectory,
141
            0755,
142
            true
143
        )
144
            && !is_dir($concurrentDirectory);
145
    }
146
}
147