Completed
Push — 57-formatter-per-extension ( 73b3c8 )
by Nicolas
40:17 queued 36:16
created

Reader::compareEnvironments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
rs 9.4286
cc 3
eloc 9
nc 3
nop 2
1
<?php
2
3
namespace Karma\Configuration;
4
5
class Reader extends AbstractReader
6
{
7
    const
8
        DEFAULT_ENVIRONMENT = 'default',
9
        DEFAULT_VALUE_FOR_ENVIRONMENT_PARAMETER = 'prod',
10
        EXTERNAL = '<external>';
11
    
12
    private
13
        $variables,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
14
        $externalReader,
15
        $groupNames,
16
        $environmentGroups;
17
    
18
    public function __construct(array $variables, array $externalVariables, array $groups = array())
19
    {
20
        parent::__construct();
21
        
22
        $this->defaultEnvironment = self::DEFAULT_VALUE_FOR_ENVIRONMENT_PARAMETER;
23
        
24
        $this->variables = $variables;
25
        
26
        $this->externalReader = null;
27
        if(! empty($externalVariables))
28
        {
29
            $this->externalReader = new Reader($externalVariables, array(), $groups);
30
        }
31
        
32
        $this->loadGroups($groups);
33
    }    
34
    
35
    private function loadGroups(array $groups)
36
    {
37
        $this->environmentGroups = array();
38
        
39
        foreach($groups as $group => $environments)
40
        {
41
            foreach($environments as $environment)
42
            {
43
                $this->environmentGroups[$environment] = $group;
44
            }    
45
        }  
46
47
        $this->groupNames = array_keys($groups);
48
    }
49
    
50
    protected function readRaw($variable, $environment = null)
51
    {
52
        if($environment === null)
53
        {
54
            $environment = $this->defaultEnvironment;
55
        }
56
        
57
        if(in_array($environment, $this->groupNames))
58
        {
59
            throw new \RuntimeException(sprintf(
60
               'Group can not be used as environment (try with group %s detected)',
61
                $environment
62
            ));
63
        }
64
        
65
        return $this->readVariable($variable, $environment);
66
    }
67
    
68
    private function readVariable($variable, $environment)
69
    {
70
        if(! array_key_exists($variable, $this->variables))
71
        {
72
            throw new \RuntimeException(sprintf(
73
                'Unknown variable %s',
74
                $variable
75
            ));   
76
        }
77
        
78
        $envs = $this->variables[$variable]['env'];
79
80
        foreach($this->getEnvironmentEntries($environment) as $entry)
81
        {
82
            if(array_key_exists($entry, $envs))
83
            {
84
                $value = $envs[$entry];
85
                
86
                if($value === self::EXTERNAL)
87
                {
88
                    $value = $this->processExternal($variable, $environment);
89
                }
90
                
91
                return $value;
92
            }
93
        }
94
        
95
        throw new \RuntimeException(sprintf(
96
            'Value not found of variable %s in environment %s (and no default value has been provided)',
97
            $variable,
98
            $environment
99
        ));
100
    }
101
    
102
    private function getEnvironmentEntries($environment)
103
    {
104
        $entries = array($environment);
105
        
106
        if(isset($this->environmentGroups[$environment]))
107
        {
108
            $entries[] = $this->environmentGroups[$environment];          
109
        }
110
        
111
        $entries[] = self::DEFAULT_ENVIRONMENT;
112
        
113
        return $entries;
114
    }
115
    
116
    private function processExternal($variable, $environment)
117
    {
118
        if(! $this->externalReader instanceof Reader)
119
        {
120
            throw new \RuntimeException(sprintf(
121
                'There is no external variables. %s can not be resolve for environment %s',
122
                $variable,
123
                $environment
124
            ));    
125
        }
126
        
127
        return $this->externalReader->read($variable, $environment);
128
    }
129
    
130
    public function getAllVariables()
131
    {
132
        return array_keys($this->variables);
133
    }
134
    
135
    public function compareEnvironments($environment1, $environment2)
136
    {
137
        $values1 = $this->getAllValuesForEnvironment($environment1);
138
        $values2 = $this->getAllValuesForEnvironment($environment2);
139
        
140
        $diff = array();
141
        
142
        foreach($values1 as $name => $value1)
143
        {
144
            $value2 = $values2[$name];
145
            
146
            if($value1 !== $value2)
147
            {
148
                $diff[$name] = array($value1, $value2);
149
            }
150
        }
151
        
152
        return $diff;
153
    }
154
}