CascadingSettingProvider   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
c 1
b 0
f 0
dl 0
loc 109
ccs 30
cts 30
cp 1
rs 10
wmc 12

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A getSettingValues() 0 3 1
A getDisplayName() 0 3 1
A add() 0 19 4
A withProvider() 0 5 1
A build() 0 3 1
A getName() 0 3 1
A findValueInstance() 0 3 1
1
<?php
2
3
/**
4
 * Settings Manager
5
 *
6
 * @license http://opensource.org/licenses/MIT
7
 * @link https://github.com/caseyamcl/settings-manager
8
 * @package caseyamcl/settings-manager
9
 * @author Casey McLaughlin <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 *
14
 *  ------------------------------------------------------------------
15
 */
16
17
declare(strict_types=1);
18
19
namespace SettingsManager\Provider;
20
21
use SettingsManager\Model\SettingValue;
22
use SettingsManager\Behavior\SettingProviderTrait;
23
use SettingsManager\Contract\SettingProvider;
24
use SettingsManager\Exception\ImmutableSettingOverrideException;
25
26
/**
27
 * Cascading setting provider
28
 *
29
 * Reads settings from multiple providers.  This is an immutable object, but it is clone-able (via the `with()` method)
30
 *
31
 * @author Casey McLaughlin <[email protected]>
32
 */
33
class CascadingSettingProvider implements SettingProvider
34
{
35
    use SettingProviderTrait;
36
37
    /**
38
     * @var array|SettingProvider[]
39
     */
40
    private $providers;
41
42
    /**
43
     * @var array|SettingValue[]
44
     */
45
    private $valuesCache = [];
46
47
    /**
48
     * Alternate constructor
49
     *
50
     * @param SettingProvider[] $provider
51
     * @return CascadingSettingProvider
52
     */
53 33
    public static function build(SettingProvider ...$provider): self
54
    {
55 33
        return new static($provider);
56
    }
57
58
    /**
59
     * CascadeProvider constructor.
60
     * @param iterable $providers
61
     */
62 33
    public function __construct(iterable $providers)
63
    {
64 33
        foreach ($providers as $provider) {
65 33
            $this->add($provider);
66
        }
67 33
    }
68
69
    /**
70
     * Add a setting provider
71
     *
72
     * @param SettingProvider $provider
73
     */
74 33
    private function add(SettingProvider $provider): void
75
    {
76 33
        $this->providers[$provider->getName()] = $provider;
77
78
        // Initialize setting values
79 33
        foreach ($provider->getSettingValues() as $value) {
80 33
            $valueCollision = array_key_exists($value->getName(), $this->valuesCache)
81 33
                && (! $this->valuesCache[$value->getName()]->isMutable());
82
83
            // If the setting is already in the out array and is immutable, throw exception.
84 33
            if ($valueCollision) {
85 3
                throw ImmutableSettingOverrideException::build(
86 3
                    $value->getName(),
87 3
                    $provider->getName(),
88 3
                    $this->valuesCache[$value->getName()]->getProviderName()
89
                );
90
            }
91
92 33
            $this->valuesCache[$value->getName()] = $value;
93
        }
94 33
    }
95
96
    /**
97
     * @return string
98
     */
99 3
    public function getName(): string
100
    {
101 3
        return 'cascade';
102
    }
103
104
    /**
105
     * @return string
106
     */
107 3
    public function getDisplayName(): string
108
    {
109 3
        return 'Cascading provider interface';
110
    }
111
112
    /**
113
     * Return a key/value set of setting names/values
114
     *
115
     * @return iterable|SettingValue[]
116
     */
117 24
    public function getSettingValues(): iterable
118
    {
119 24
        return $this->valuesCache;
120
    }
121
122
    /**
123
     * @param string $name
124
     * @return SettingProvider|null
125
     */
126 21
    public function findValueInstance(string $name): ?SettingValue
127
    {
128 21
        return $this->getSettingValues()[$name] ?? null;
129
    }
130
131
    /**
132
     * Clone this, adding a provider to the cloned instance
133
     *
134
     * @param SettingProvider $provider
135
     * @return $this
136
     */
137 6
    public function withProvider(SettingProvider $provider): self
138
    {
139 6
        $that = clone $this;
140 6
        $that->add($provider);
141 3
        return $that;
142
    }
143
}
144