Completed
Push — master ( bf6ec7...65b5b4 )
by Arne
02:10
created

ConfigurationFileReader   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 11

Importance

Changes 0
Metric Value
wmc 10
c 0
b 0
f 0
lcom 0
cbo 11
dl 0
loc 76
rs 10

3 Methods

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