Passed
Push — master ( 0b7dea...b9611f )
by Mariano
04:34
created

ConfigBuilder::getConfigurationFromConfigFile()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 2
b 0
f 0
nc 4
nop 0
dl 0
loc 14
rs 10
1
<?php
2
3
namespace Mcustiel\Phiremock\Server\Utils\Config;
4
5
use DomainException;
6
use Exception;
7
use Mcustiel\Phiremock\Server\Cli\Options\ExpectationsDirectory;
8
use Mcustiel\Phiremock\Server\Factory\Factory;
9
use Mcustiel\Phiremock\Server\Utils\HomePathService;
10
11
class ConfigBuilder
12
{
13
    private const DEFAULT_IP = '0.0.0.0';
14
    private const DEFAULT_PORT = 8086;
15
16
    /** @var array */
17
    private static $defaultConfig;
18
19
    /** @var Directory|null */
20
    private $configPath;
21
22
    /** @throws Exception */
23
    public function __construct(?Directory $configPath)
24
    {
25
        if (self::$defaultConfig === null) {
26
            self::$defaultConfig = [
27
                Config::PORT             => self::DEFAULT_PORT,
28
                Config::IP               => self::DEFAULT_IP,
29
                Config::EXPECTATIONS_DIR => self::getDefaultExpectationsDir()->asString(),
30
                Config::DEBUG            => false,
31
                Config::FACTORY_CLASS    => Factory::class,
32
            ];
33
        }
34
        $this->configPath = $configPath;
35
    }
36
37
    /** @throws Exception */
38
    public function build(array $cliConfig): Config
39
    {
40
        $config = self::$defaultConfig;
41
42
        $fileConfiguration = $this->getConfigurationFromConfigFile();
43
        $extraKeys = array_diff_key($fileConfiguration, self::$defaultConfig);
44
        if (!empty($extraKeys)) {
45
            throw new DomainException('Extra keys in configuration file: ' . implode(',', $extraKeys));
46
        }
47
48
        return new Config(array_replace($config, $fileConfiguration, $cliConfig));
49
    }
50
51
    /** @throws Exception */
52
    public static function getDefaultExpectationsDir(): ExpectationsDirectory
53
    {
54
        return new ExpectationsDirectory(
55
            HomePathService::getHomePath()->getFullSubpathAsString(
56
                '.phiremock' . DIRECTORY_SEPARATOR . 'expectations'
57
            )
58
        );
59
    }
60
61
    /** @throws Exception */
62
    protected function getConfigurationFromConfigFile(): array
63
    {
64
        if ($this->configPath) {
65
            $configFiles = ['.phiremock', '.phiremock.dist'];
66
            foreach ($configFiles as $configFileName) {
67
                $configFilePath = $this->configPath->getFullSubpathAsString($configFileName);
68
                if (file_exists($configFilePath)) {
69
                    return require $configFilePath;
70
                }
71
            }
72
            throw new Exception('No config file found in: ' . $this->configPath->asString());
73
        }
74
75
        return $this->searchFileAndGetConfig();
76
    }
77
78
    protected function searchFileAndGetConfig(): array
79
    {
80
        $configFiles = [
81
            __DIR__ . '/../../../../../../.phiremock',
82
            __DIR__ . '/../../../../../../.phiremock.dist',
83
            __DIR__ . '/../../../.phiremock',
84
            __DIR__ . '/../../../.phiremock.dist',
85
            getcwd() . '/.phiremock',
86
            getcwd() . '/.phiremock.dist',
87
            HomePathService::getHomePath()->getFullSubpathAsString(
88
                '.phiremock' . DIRECTORY_SEPARATOR . 'config'
89
            ),
90
            '.phiremock',
91
            '.phiremock.dist',
92
        ];
93
        foreach ($configFiles as $configFilePath) {
94
            if (file_exists($configFilePath)) {
95
                return require $configFilePath;
96
            }
97
        }
98
        return [];
99
    }
100
}
101