Completed
Push — master ( 8b0d56...e2f78c )
by Arne
01:57
created

ConfigurationFileReader::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
namespace Storeman;
4
5
use Storeman\Exception\ConfigurationException;
6
use Storeman\Exception\Exception;
7
use Storeman\Validation\ContainerConstraintValidatorFactory;
8
use Symfony\Component\Validator\Validation;
9
use Symfony\Component\Validator\Validator\ValidatorInterface;
10
11
class ConfigurationFileReader
12
{
13
    public const CONFIG_CLASS = Configuration::class;
14
15
16
    /**
17
     * @var Container
18
     */
19
    protected $container;
20
21
    public function __construct(Container $container = null)
22
    {
23
        $this->container = $container ?: new Container();
24
    }
25
26
    public function getConfiguration(string $configurationFilePath): Configuration
27
    {
28
        $configurationFilePath = PathUtils::getAbsolutePath($configurationFilePath);
29
30
        if (!is_file($configurationFilePath) || !is_readable($configurationFilePath))
31
        {
32
            throw new Exception("Configuration file {$configurationFilePath} is not a readable file.");
33
        }
34
35
        if (($json = file_get_contents($configurationFilePath)) === false)
36
        {
37
            throw new Exception("Failed to read config file {$configurationFilePath}.");
38
        }
39
40
        if (($array = json_decode($json, true)) === null)
41
        {
42
            throw new Exception("Malformed configuration file: {$configurationFilePath}.");
43
        }
44
45
46
        // default values
47
        $array = ArrayUtils::merge([
48
            'path' => dirname($configurationFilePath),
49
            'identity' => sprintf('%s@%s', get_current_user(), gethostname()),
50
        ], $array);
51
52
53
        try
54
        {
55
            $className = static::CONFIG_CLASS;
56
57
            /** @var Configuration $configuration */
58
            $configuration = new $className();
59
            $configuration->exchangeArray($array);
60
        }
61
        catch (\InvalidArgumentException $exception)
62
        {
63
            throw new ConfigurationException('', 0, $exception);
64
        }
65
66
67
        // validate configuration
68
        $constraintViolations = $this->getValidator()->validate($configuration);
69
        if ($constraintViolations->count())
70
        {
71
            $violation = $constraintViolations->get(0);
72
73
            throw new ConfigurationException("{$violation->getPropertyPath()} - {$violation->getMessage()}");
74
        }
75
76
        return $configuration;
77
    }
78
79
    protected function getValidator(): ValidatorInterface
80
    {
81
        return Validation::createValidatorBuilder()
82
            ->setConstraintValidatorFactory(new ContainerConstraintValidatorFactory($this->container))
83
            ->addMethodMapping('loadValidatorMetadata')
84
            ->getValidator();
85
    }
86
}
87