Test Failed
Pull Request — master (#10)
by Yo
02:35
created

ConfigurationUpdater   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 7
dl 0
loc 204
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
B update() 0 32 1
C getEntityId() 0 27 7
A updateIfDefined() 0 4 2
A mergeValueList() 0 8 1
B updateList() 0 38 5
C updateScriptList() 0 37 7
B mergeEntity() 0 14 5
1
<?php
2
namespace Yoanm\ComposerConfigManager\Application\Updater;
3
4
use Yoanm\ComposerConfigManager\Domain\Model\Author;
5
use Yoanm\ComposerConfigManager\Domain\Model\Autoload;
6
use Yoanm\ComposerConfigManager\Domain\Model\Configuration;
7
use Yoanm\ComposerConfigManager\Domain\Model\Package;
8
use Yoanm\ComposerConfigManager\Domain\Model\Script;
9
use Yoanm\ComposerConfigManager\Domain\Model\SuggestedPackage;
10
use Yoanm\ComposerConfigManager\Domain\Model\Support;
11
12
class ConfigurationUpdater
13
{
14
    /**
15
     * @param Configuration $baseConfiguration
16
     * @param Configuration $newConfiguration
17
     *
18
     * @return Configuration
19
     */
20
    public function update(Configuration $baseConfiguration, Configuration $newConfiguration)
21
    {
22
        return new Configuration(
23
            $this->updateIfDefined($newConfiguration->getPackageName(), $baseConfiguration->getPackageName()),
24
            $this->updateIfDefined($newConfiguration->getType(), $baseConfiguration->getType()),
25
            $this->updateIfDefined($newConfiguration->getLicense(), $baseConfiguration->getLicense()),
26
            $this->updateIfDefined($newConfiguration->getPackageVersion(), $baseConfiguration->getPackageVersion()),
27
            $this->updateIfDefined($newConfiguration->getDescription(), $baseConfiguration->getDescription()),
28
            $this->mergeValueList($newConfiguration->getKeywordList(), $baseConfiguration->getKeywordList()),
29
            $this->updateList($newConfiguration->getAuthorList(), $baseConfiguration->getAuthorList()),
30
            $this->updateList(
31
                $newConfiguration->getProvidedPackageList(),
32
                $baseConfiguration->getProvidedPackageList()
33
            ),
34
            $this->updateList(
35
                $newConfiguration->getSuggestedPackageList(),
36
                $baseConfiguration->getSuggestedPackageList()
37
            ),
38
            $this->updateList($newConfiguration->getSupportList(), $baseConfiguration->getSupportList()),
39
            $this->updateList($newConfiguration->getAutoloadList(), $baseConfiguration->getAutoloadList()),
40
            $this->updateList($newConfiguration->getAutoloadDevList(), $baseConfiguration->getAutoloadDevList()),
41
            $this->updateList(
42
                $newConfiguration->getRequiredPackageList(),
43
                $baseConfiguration->getRequiredPackageList()
44
            ),
45
            $this->updateList(
46
                $newConfiguration->getRequiredDevPackageList(),
47
                $baseConfiguration->getRequiredDevPackageList()
48
            ),
49
            $this->updateScriptList($newConfiguration->getScriptList(), $baseConfiguration->getScriptList())
50
        );
51
    }
52
53
    /**
54
     * @param object $entity
55
     *
56
     * @return null|string
57
     */
58
    public function getEntityId($entity)
59
    {
60
        switch (true) {
61
            case $entity instanceof Author:
62
                $id = $entity->getName();
63
                break;
64
            case $entity instanceof SuggestedPackage:
65
                $id = $entity->getName();
66
                break;
67
            case $entity instanceof Support:
68
                $id = $entity->getType();
69
                break;
70
            case $entity instanceof Autoload:
71
                $id = $entity->getType().'#'.$entity->getNamespace();
72
                break;
73
            case $entity instanceof Package:
74
                $id = $entity->getName();
75
                break;
76
            case $entity instanceof Script:
77
                $id = $entity->getName();
78
                break;
79
            default:
80
                $id = null;
81
        };
82
83
        return $id;
84
    }
85
86
    /**
87
     * @param string $baseValue
88
     * @param string $newValue
89
     *
90
     * @return string
91
     */
92
    protected function updateIfDefined($newValue, $baseValue)
93
    {
94
        return $newValue ? $newValue : $baseValue;
95
    }
96
97
    /**
98
     * @param string[] $newList
99
     * @param string[] $oldList
100
     *
101
     * @return string[]
102
     */
103
    protected function mergeValueList(array $oldList, array $newList)
104
    {
105
        return array_values(
106
            array_unique(
107
                array_merge($newList, $oldList)
108
            )
109
        );
110
    }
111
112
    /**
113
     * @param array $newEntityList
114
     * @param array $oldEntityList
115
     *
116
     * @return array
117
     */
118
    protected function updateList(array $newEntityList, array $oldEntityList)
119
    {
120
        $listTmp = [];
121
        $self = $this;
122
        foreach ($newEntityList as $newEntity) {
123
            // Search for an old entry
124
            $newEntityId = $this->getEntityId($newEntity);
125
            $oldEntityMatches = array_filter(
126
                $oldEntityList,
127
                function ($oldEntity) use ($newEntityId, $self) {
128
                    return $self->getEntityId($oldEntity) == $newEntityId;
129
                }
130
            );
131
            if (count($oldEntityMatches)) {
132
                $oldEntity = array_shift($oldEntityMatches);
133
                $newEntity = $this->mergeEntity($oldEntity, $newEntity);
134
                $oldEntityList = array_map(
135
                    function ($oldEntity) use ($newEntityId, $newEntity, $self) {
136
                        return $self->getEntityId($oldEntity) == $newEntityId
137
                            ? $newEntity
138
                            : $oldEntity
139
                        ;
140
                    },
141
                    $oldEntityList
142
                );
143
            } else {
144
                $listTmp[] = $newEntity;
145
            }
146
        }
147
148
        // Merge remaining entities that have not been already merged
149
        $list = [];
150
        foreach (array_reverse($oldEntityList, true) as $entity) {
151
            array_unshift($list, $entity);
152
        }
153
154
        return array_merge($list, $listTmp);
155
    }
156
157
    /**
158
     * @param Script[] $newEntityList
159
     * @param Script[] $oldEntityList
160
     *
161
     * @return Script[]
162
     */
163
    protected function updateScriptList(array $newEntityList, array $oldEntityList)
164
    {
165
        $mergedEntityIdList = [];
166
        $self = $this;
167
        $normalizedNewEntityList = [];
168
        foreach ($newEntityList as $newEntity) {
169
            // Search for an old entry
170
            $newEntityId = $this->getEntityId($newEntity);
171
            $oldEntityMatches = array_filter(
172
                $oldEntityList,
173
                function ($oldEntity) use ($newEntityId, $self) {
174
                    return $self->getEntityId($oldEntity) == $newEntityId;
175
                }
176
            );
177
            if (count($oldEntityMatches)) {
178
                $mergedEntityIdList[$newEntityId] = true;
179
            }
180
            $normalizedNewEntityList[] = $newEntity;
181
        }
182
        // Merge remaining entities that have not been already merged
183
        $normalizedOldEntityList = [];
184
        foreach ($oldEntityList as $oldEntity) {
185
            if (!array_key_exists($this->getEntityId($oldEntity), $mergedEntityIdList)) {
186
                $normalizedOldEntityList[] = $oldEntity;
187
            } else {
188
                $oldEntityId = $this->getEntityId($oldEntity);
189
                foreach ($normalizedNewEntityList as $newEntityKey => $newEntity) {
190
                    if ($self->getEntityId($newEntity) == $oldEntityId) {
191
                        $normalizedOldEntityList[] = $newEntity;
192
                        unset($normalizedNewEntityList[$newEntityKey]);
193
                    }
194
                }
195
            }
196
        }
197
198
        return array_merge($normalizedOldEntityList, $normalizedNewEntityList);
199
    }
200
201
    protected function mergeEntity($oldEntity, $newEntity)
202
    {
203
        switch (true) {
204
            case $newEntity instanceof Author && $oldEntity instanceof Author:
205
                return new Author(
206
                    $newEntity->getName(),
207
                    $newEntity->getEmail() ? $newEntity->getEmail() : $oldEntity->getEmail(),
208
                    $newEntity->getRole() ? $newEntity->getRole() : $oldEntity->getRole()
209
                );
210
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
211
        }
212
213
        return $newEntity;
214
    }
215
}
216