Completed
Push — master ( a4e6dd...a851cc )
by Arne
02:45
created

Configuration::getArrayCopy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
3
namespace Storeman;
4
5
use Storeman\Exception\Exception;
6
use Symfony\Component\Validator\Mapping\ClassMetadata;
7
use Zend\Stdlib\ArraySerializableInterface;
8
use Symfony\Component\Validator\Constraints as Assert;
9
10
class Configuration implements ArraySerializableInterface
11
{
12
    public const VAULT_CONFIG_CLASS = VaultConfiguration::class;
13
14
15
    /**
16
     * The local base path of the archive.
17
     *
18
     * @var string
19
     */
20
    protected $path = './';
21
22
    /**
23
     * Set of excluded paths.
24
     *
25
     * @var string[]
26
     */
27
    protected $exclude = [];
28
29
    /**
30
     * Identity to be visible in synchronization log.
31
     *
32
     * @var string
33
     */
34
    protected $identity = 'unknown';
35
36
    /**
37
     * Identifier of the index builder to use.
38
     *
39
     * @var string
40
     */
41
    protected $indexBuilder = 'standard';
42
43
    /**
44
     * Array of vault configurations.
45
     *
46
     * @var VaultConfiguration[]
47
     */
48
    protected $vaults = [];
49
50
    /**
51
     * @return string
52
     */
53
    public function getPath(): string
54
    {
55
        return $this->path;
56
    }
57
58
    /**
59
     * @param string $path
60
     *
61
     * @return Configuration
62
     */
63
    public function setPath(string $path): Configuration
64
    {
65
        if (substr($path, -1) !== DIRECTORY_SEPARATOR)
66
        {
67
            $path .= DIRECTORY_SEPARATOR;
68
        }
69
70
        $this->path = $path;
71
72
        return $this;
73
    }
74
75
    /**
76
     * @return \string[]
77
     */
78
    public function getExclude(): array
79
    {
80
        return $this->exclude;
81
    }
82
83
    /**
84
     * @param \string[] $paths
85
     *
86
     * @return Configuration
87
     */
88
    public function setExclude(array $paths): Configuration
89
    {
90
        $this->exclude = array_values($paths);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_values($paths) of type array<integer,object<string>> is incompatible with the declared type array<integer,string> of property $exclude.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
91
92
        return $this;
93
    }
94
95
    /**
96
     * @param string $path
97
     *
98
     * @return Configuration
99
     */
100
    public function addExclusion(string $path): Configuration
101
    {
102
        $this->exclude[] = $path;
103
104
        return $this;
105
    }
106
107
    /**
108
     * @return string
109
     */
110
    public function getIdentity(): string
111
    {
112
        return $this->identity;
113
    }
114
115
    /**
116
     * @param string $identity
117
     *
118
     * @return Configuration
119
     */
120
    public function setIdentity(string $identity): Configuration
121
    {
122
        $this->identity = $identity;
123
124
        return $this;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getIndexBuilder(): string
131
    {
132
        return $this->indexBuilder;
133
    }
134
135
    /**
136
     * @param string $indexBuilder
137
     * @return $this
138
     */
139
    public function setIndexBuilder(string $indexBuilder): Configuration
140
    {
141
        $this->indexBuilder = $indexBuilder;
142
143
        return $this;
144
    }
145
146
    /**
147
     * @return VaultConfiguration[]
148
     */
149
    public function getVaults(): array
150
    {
151
        return $this->vaults;
152
    }
153
154
    /**
155
     * @param string $title
156
     * @return bool
157
     */
158
    public function hasVault(string $title): bool
159
    {
160
        return $this->getVaultConfiguration($title) !== null;
161
    }
162
163
    /**
164
     * @param string $title
165
     *
166
     * @return VaultConfiguration
167
     */
168
    public function getVault(string $title): VaultConfiguration
169
    {
170
        if ($vaultConfiguration = $this->getVaultConfiguration($title))
171
        {
172
            return $vaultConfiguration;
173
        }
174
175
        throw new \InvalidArgumentException("Unknown vault configuration requested: {$title}");
176
    }
177
178
    /**
179
     * @internal Use VaultConfiguration constructor
180
     * @param VaultConfiguration $configuration
181
     *
182
     * @return Configuration
183
     * @throws Exception
184
     */
185
    public function addVault(VaultConfiguration $configuration): Configuration
186
    {
187
        if (array_search($configuration, $this->vaults) === false)
188
        {
189
            if ($this->hasVault($configuration->getTitle()))
190
            {
191
                throw new Exception(sprintf('Trying to add vault with duplicate title %s.', $configuration->getTitle()));
192
            }
193
194
            $this->vaults[] = $configuration;
195
        }
196
197
        return $this;
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function exchangeArray(array $array)
204
    {
205
        if ($diff = array_diff(array_keys($array), array_keys(get_object_vars($this))))
206
        {
207
            throw new \InvalidArgumentException("Invalid index(es): " . implode(',', $diff));
208
        }
209
210
        foreach ($array as $key => $value)
211
        {
212
            if ($key === 'vaults')
213
            {
214
                if (!is_array($value))
215
                {
216
                    throw new \InvalidArgumentException();
217
                }
218
219
                $this->vaults = [];
220
221
                foreach ($value as $val)
222
                {
223
                    if (!is_array($val))
224
                    {
225
                        throw new \InvalidArgumentException();
226
                    }
227
228
                    $className = static::VAULT_CONFIG_CLASS;
229
230
                    /** @var VaultConfiguration $vaultConfig */
231
                    $vaultConfig = new $className($this);
232
                    $vaultConfig->exchangeArray($val);
233
                }
234
            }
235
            else
236
            {
237
                // using setter to prevent skipping validation
238
                call_user_func([$this, 'set' . ucfirst($key)], $value);
239
            }
240
        }
241
    }
242
243
    /**
244
     * {@inheritdoc}
245
     */
246
    public function getArrayCopy()
247
    {
248
        $return = get_object_vars($this);
249
        $return['vaults'] = array_values(array_map(function(VaultConfiguration $vaultConfiguration) {
250
251
            return $vaultConfiguration->getArrayCopy();
252
253
        }, $this->vaults));
254
255
        return $return;
256
    }
257
258
    protected function getVaultConfiguration(string $title): ?VaultConfiguration
259
    {
260
        foreach ($this->vaults as $vaultConfiguration)
261
        {
262
            if ($vaultConfiguration->getTitle() === $title)
263
            {
264
                return $vaultConfiguration;
265
            }
266
        }
267
268
        return null;
269
    }
270
271
    public static function loadValidatorMetadata(ClassMetadata $metadata)
272
    {
273
        $metadata->addPropertyConstraint('path', new Assert\NotBlank());
274
        $metadata->addPropertyConstraint('identity', new Assert\NotBlank());
275
        $metadata->addPropertyConstraint('vaults', new Assert\Count(['min' => 1]));
276
    }
277
}
278