Completed
Push — master ( 2cde75...6c52d6 )
by Arne
02:04
created

Configuration   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 226
Duplicated Lines 1.77 %

Coupling/Cohesion

Components 3
Dependencies 5

Importance

Changes 0
Metric Value
wmc 24
lcom 3
cbo 5
dl 4
loc 226
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getPath() 0 4 1
A setPath() 0 11 2
A getExclude() 0 4 1
A setExclude() 0 6 1
A addExclusion() 0 6 1
A getIdentity() 0 4 1
A setIdentity() 0 6 1
A getVaults() 0 4 1
A hasVault() 0 4 1
A getVaultByTitle() 0 9 2
A addVault() 0 11 2
C exchangeArray() 0 41 7
A getArrayCopy() 0 11 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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;
35
36
    /**
37
     * Map of vault configurations by identifier.
38
     *
39
     * @var VaultConfiguration[]
40
     */
41
    protected $vaults = [];
42
43
    public function __construct(string $localPath = './')
44
    {
45
        $this->setPath($localPath);
46
    }
47
48
    /**
49
     * @return string
50
     */
51
    public function getPath(): string
52
    {
53
        return $this->path;
54
    }
55
56
    /**
57
     * @param string $path
58
     *
59
     * @return Configuration
60
     */
61
    public function setPath(string $path): Configuration
62
    {
63
        if (substr($path, -1) !== DIRECTORY_SEPARATOR)
64
        {
65
            $path .= DIRECTORY_SEPARATOR;
66
        }
67
68
        $this->path = $path;
69
70
        return $this;
71
    }
72
73
    /**
74
     * @return \string[]
75
     */
76
    public function getExclude(): array
77
    {
78
        return $this->exclude;
79
    }
80
81
    /**
82
     * @param \string[] $paths
83
     *
84
     * @return Configuration
85
     */
86
    public function setExclude(array $paths): Configuration
87
    {
88
        $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...
89
90
        return $this;
91
    }
92
93
    /**
94
     * @param string $path
95
     *
96
     * @return Configuration
97
     */
98
    public function addExclusion(string $path): Configuration
99
    {
100
        $this->exclude[] = $path;
101
102
        return $this;
103
    }
104
105
    /**
106
     * @return string
107
     */
108
    public function getIdentity(): ?string
109
    {
110
        return $this->identity;
111
    }
112
113
    /**
114
     * @param string $identity
115
     *
116
     * @return Configuration
117
     */
118
    public function setIdentity(string $identity): Configuration
119
    {
120
        $this->identity = $identity;
121
122
        return $this;
123
    }
124
125
    /**
126
     * @return VaultConfiguration[]
127
     */
128
    public function getVaults(): array
129
    {
130
        return $this->vaults;
131
    }
132
133
    /**
134
     * @param string $title
135
     * @return bool
136
     */
137
    public function hasVault(string $title): bool
138
    {
139
        return isset($this->vaults[$title]);
140
    }
141
142
    /**
143
     * @param string $title
144
     *
145
     * @return VaultConfiguration
146
     */
147
    public function getVaultByTitle(string $title): VaultConfiguration
148
    {
149
        if (!isset($this->vaults[$title]))
150
        {
151
            throw new \InvalidArgumentException("Unknown vault configuration requested: {$title}");
152
        }
153
154
        return $this->vaults[$title];
155
    }
156
157
    /**
158
     * @param VaultConfiguration $configuration
159
     *
160
     * @return Configuration
161
     * @throws Exception
162
     */
163
    public function addVault(VaultConfiguration $configuration): Configuration
164
    {
165
        if (isset($this->vaults[$configuration->getTitle()]))
166
        {
167
            throw new Exception(sprintf('Trying to add vault with duplicate title %s.', $configuration->getTitle()));
168
        }
169
170
        $this->vaults[$configuration->getTitle()] = $configuration;
171
172
        return $this;
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178
    public function exchangeArray(array $array)
179
    {
180
        if ($diff = array_diff(array_keys($array), array_keys(get_object_vars($this))))
181
        {
182
            throw new \InvalidArgumentException("Invalid index(es): " . implode(',', $diff));
183
        }
184
185
        foreach ($array as $key => $value)
186
        {
187
            if ($key === 'vaults')
188
            {
189
                if (!is_array($value))
190
                {
191
                    throw new \InvalidArgumentException();
192
                }
193
194
                $this->vaults = [];
195
196
                foreach ($value as $val)
197
                {
198
                    if (!is_array($val))
199
                    {
200
                        throw new \InvalidArgumentException();
201
                    }
202
203
                    $className = static::VAULT_CONFIG_CLASS;
204
205
                    /** @var VaultConfiguration $vaultConfig */
206
                    $vaultConfig = new $className();
207
                    $vaultConfig->exchangeArray($val);
208
209
                    $this->addVault($vaultConfig);
210
                }
211
            }
212
            else
213
            {
214
                // using setter to prevent skipping validation
215
                call_user_func([$this, 'set' . ucfirst($key)], $value);
216
            }
217
        }
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223
    public function getArrayCopy()
224
    {
225
        $return = get_object_vars($this);
226
        $return['vaults'] = array_values(array_map(function(VaultConfiguration $vaultConfiguration) {
227
228
            return $vaultConfiguration->getArrayCopy();
229
230
        }, $this->vaults));
231
232
        return $return;
233
    }
234
235
    public static function loadValidatorMetadata(ClassMetadata $metadata)
236
    {
237
        $metadata->addPropertyConstraint('path', new Assert\NotBlank());
238
        $metadata->addPropertyConstraint('identity', new Assert\NotBlank());
239
        $metadata->addPropertyConstraint('vaults', new Assert\Count(['min' => 1]));
240
    }
241
}
242