Issues (56)

Manager/ConfigManager.php (2 issues)

Labels
1
<?php
2
/**
3
 * @author    oliverde8<[email protected]>
4
 * @category  @category  oliverde8/ComfyBundle
5
 */
6
7
namespace oliverde8\ComfyBundle\Manager;
8
9
use oliverde8\AssociativeArraySimplified\AssociativeArray;
10
use oliverde8\ComfyBundle\Exception\UnknownConfigPathException;
11
use oliverde8\ComfyBundle\Exception\UnknownScopeException;
12
use oliverde8\ComfyBundle\Model\ConfigInterface;
13
use oliverde8\ComfyBundle\Resolver\ScopeResolverInterface;
14
use oliverde8\ComfyBundle\Storage\StorageInterface;
15
16
class ConfigManager implements ConfigManagerInterface
17
{
18
    /** @var ScopeResolverInterface */
19
    protected $scopeResolver;
20
21
    /** @var StorageInterface */
22
    protected $storage;
23
24
    /** @var AssociativeArray */
25
    protected $configTree;
26
27
    /** @var ConfigInterface[] */
28
    protected $configs;
29
30
    /** @var array */
31
    protected $configValues;
32
33
    /** @var array */
34
    protected $configParentInheritance;
35
36
    protected array $resolvedScopes = [];
37
38
    /**
39
     * ConfigManager constructor.
40
     *
41
     * @param ScopeResolverInterface $scopeResolver
42
     * @param StorageInterface $storage
43
     */
44
    public function __construct(ScopeResolverInterface $scopeResolver, StorageInterface $storage)
45
    {
46
        $this->scopeResolver = $scopeResolver;
47
        $this->storage = $storage;
48
        // TODO make it configurable.
49
        $this->configTree = new AssociativeArray();
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55
    public function set(string $configPath, ?string $value, string $scope = null): ConfigManagerInterface
56
    {
57
        $this->validatePath($configPath);
58
        $scope = $this->validateScope($scope);
59
60
        if (!is_null($value)) {
61
            $this->configValues[$scope][$configPath] = $value;
62
            $this->configParentInheritance[$scope][$configPath] = false;
63
        } else {
64
            $this->scopeResolver->inherits($scope);
65
            $previousScope = $this->scopeResolver->getScope($this->scopeResolver->inherits($scope));
66
            $this->configValues[$scope][$configPath] = $this->configValues[$previousScope][$configPath];
67
            $this->configParentInheritance[$scope][$configPath] = true;
68
        }
69
70
        $this->storage->save($configPath, $scope, $value);
0 ignored issues
show
It seems like $value can also be of type null; however, parameter $value of oliverde8\ComfyBundle\St...torageInterface::save() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
        $this->storage->save($configPath, $scope, /** @scrutinizer ignore-type */ $value);
Loading history...
71
        return $this;
72
    }
73
74
    /**
75
     * @inheritDoc
76
     */
77
    public function get(string $configPath, string $scope = null): ?string
78
    {
79
        $this->validatePath($configPath);
80
        $scope = $this->validateScope($scope);
81
82
        return $this->configValues[$scope][$configPath];
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88
    public function doesInhertit(string $configPath, string $scope = null): bool
89
    {
90
        $this->validatePath($configPath);
91
        $scope = $this->validateScope($scope);
92
        return $this->configParentInheritance[$scope][$configPath];
93
    }
94
95
    /**
96
     * @inheritDoc
97
     */
98
    public function getAllConfigs(string $scope = null): AssociativeArray
99
    {
100
        return $this->configTree;
101
    }
102
103
    /**
104
     * @inheritDoc
105
     */
106
    public function registerConfig(ConfigInterface $config)
107
    {
108
        $this->configTree->set($config->getPath(), $config);
109
        $this->configs[$config->getPath()] = $config;
110
    }
111
112
113
    protected function validateScope($scope)
114
    {
115
        if (isset($this->resolvedScopes[$scope])) {
116
            return $this->resolvedScopes[$scope];
117
        }
118
119
        if (!$this->scopeResolver->validateScope($scope)) {
120
            throw new UnknownScopeException("Scope '$scope' was not found!");
121
        }
122
123
        $scopeValue = $this->scopeResolver->getScope($scope);
124
        $this->resolvedScopes[$scope] = $scopeValue;
125
126
        if (!isset($this->configValues[$scopeValue])) {
127
            // TODO first check in cache.
128
            $this->loadScopeFromStorage($scopeValue);
129
        }
130
131
        return $scopeValue;
132
    }
133
134
    protected function validatePath($path)
135
    {
136
        if (!isset($this->configs[$path])) {
137
            throw new UnknownConfigPathException("No configuration with path: '$path' has been registered");
138
        }
139
    }
140
141
    protected function loadScopeFromStorage($scope)
142
    {
143
        $scopes = [];
144
145
        $lastScope = $scope;
146
        do {
147
            $scopes[] = $lastScope;
148
            $lastScope = $this->scopeResolver->inherits($lastScope);
149
        } while(!is_null($lastScope));
150
151
        $values = $this->storage->load($scopes);
152
        $previousScope = null;
153
154
        foreach (array_reverse($scopes) as $scope) {
0 ignored issues
show
$scope is overwriting one of the parameters of this function.
Loading history...
155
            foreach ($this->configs as $config) {
156
                if (is_null($previousScope)) {
157
                    $previousValue = $config->getDefaultValue();
158
                } else {
159
                    $previousValue = $this->configValues[$previousScope][$config->getPath()];
160
                }
161
162
                $this->configParentInheritance[$scope][$config->getPath()] = !AssociativeArray::checkKeyExist($values, [$scope, $config->getPath()]);
163
                $this->configValues[$scope][$config->getPath()] = AssociativeArray::getFromKey($values, [$scope, $config->getPath()], $previousValue);
164
            }
165
            $previousScope = $scope;
166
        }
167
    }
168
}
169