Passed
Branch master (73ca69)
by Boudry
03:33
created

Result   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Coupling/Cohesion

Components 4
Dependencies 5

Test Coverage

Coverage 52.75%

Importance

Changes 0
Metric Value
wmc 42
lcom 4
cbo 5
dl 0
loc 207
ccs 48
cts 91
cp 0.5275
rs 8.295
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A rewind() 0 3 1
A current() 0 3 1
A key() 0 3 1
A next() 0 3 1
A valid() 0 3 2
A offsetSet() 0 3 1
A offsetExists() 0 3 1
A offsetUnset() 0 3 1
A offsetGet() 0 3 1
A count() 0 3 1
A __construct() 0 13 1
B getResultAsArray() 0 16 6
A getResultAsString() 0 4 1
A getOriginalArrayWithString() 0 4 1
A getResultAsInternalKey() 0 4 1
A getStats() 0 3 1
A getWinner() 0 3 1
A getLoser() 0 3 1
A getCondorcetWinner() 0 3 1
A getCondorcetLoser() 0 3 1
C makeUserResult() 0 24 7
A addWarning() 0 6 1
A getWarning() 0 16 4
A getClassGenerator() 0 3 1
A getMethod() 0 3 1
A getBuildTimeStamp() 0 3 1
A getCondorcetElectionGeneratorVersion() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Result often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Result, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
    Condorcet PHP Class, with Schulze Methods and others !
4
5
    By Julien Boudry - MIT LICENSE (Please read LICENSE.txt)
6
    https://github.com/julien-boudry/Condorcet
7
*/
8
declare(strict_types=1);
9
10
namespace Condorcet;
11
12
use Condorcet\CondorcetException;
13
use Condorcet\CondorcetVersion;
14
use Condorcet\Candidate;
15
use Condorcet\Election;
16
use Condorcet\Linkable;
17
use Condorcet\Vote;
18
19
20
class Result implements \ArrayAccess, \Countable, \Iterator 
21
{
22
    use CondorcetVersion;
23
24
    // Implement Iterator
25
26
    function rewind() :void {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
27
        reset($this->_UserResult);
28
    }
29
30
    function current () {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
31
        return current($this->_UserResult);
32
    }
33
34
    function key () : int {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
35
        return key($this->_UserResult);
36
    }
37
38
    function next () : void {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
39
        next($this->_UserResult);
40
    }
41
42
    function valid () : bool {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
43
        return (key($this->_UserResult) === null) ? false : true;
44
    }
45
46
    // Implement ArrayAccess
47
48
    public function offsetSet ($offset, $value) : void {
49
        throw new CondorcetException (0,"Can't change a result");
50
    }
51
52
    public function offsetExists ($offset) : bool {
53
        return isset($this->_UserResult[$offset]);
54
    }
55
56
    public function offsetUnset ($offset) : void {
57
        throw new CondorcetException (0,"Can't change a result");
58
    }
59
60 2
    public function offsetGet ($offset) {
61 2
        return $this->_UserResult[$offset] ?? null;
62
    }
63
64
    // Implement Countable
65
66 2
    public function count () : int {
67 2
        return count($this->_UserResult);
68
    }
69
70
71
/////////// CONSTRUCTOR ///////////
72
73
    protected $_Result;
74
    protected $_UserResult;
75
    protected $_stringResult;
76
    protected $_CondorcetWinner;
77
    protected $_CondorcetLoser;
78
79
    protected $_Stats;
80
81
    protected $_warning = [];
82
83
    protected $_BuildTimeStamp;
84
    protected $_fromMethod;
85
    protected $_byClass;
86
    protected $_ElectionCondorcetVersion;
87
88
89 4
    public function __construct (string $fromMethod, string $byClass, Election $election, array $result, $stats)
90
    {
91 4
        $this->_Result = $result;
92 4
        $this->_UserResult = $this->makeUserResult($election);
93 4
        $this->_stringResult = $this->getResultAsArray(true);
94 4
        $this->_Stats = $stats;
95 4
        $this->_fromMethod = $fromMethod;
96 4
        $this->_byClass = $byClass;
97 4
        $this->_ElectionCondorcetVersion = $election->getObjectVersion();
98 4
        $this->_CondorcetWinner = $election->getWinner();
99 4
        $this->_CondorcetLoser = $election->getLoser();
100 4
        $this->_BuildTimeStamp = microtime(true);
101 4
    }
102
103
104
/////////// Get Result ///////////
105
106 4
    public function getResultAsArray (bool $convertToString = false) : array
107
    {
108 4
        $r = $this->_UserResult;
109
110 4
        foreach ($r as &$rank) :
111 4
            if (count($rank) === 1) :
112 4
                $rank = ($convertToString) ? (string) $rank[0] : $rank[0];
113 3
            elseif ($convertToString) :
114 3
                foreach ($rank as &$subRank) :
115 4
                    $subRank = (string) $subRank;
116
                endforeach;
117
            endif;
118
        endforeach;
119
120 4
        return $r;
121
    }
122
123
    public function getResultAsString ()
124
    {
125
        return Vote::getRankingAsString($this->getResultAsArray(true));
126
    }
127
128
    public function getOriginalArrayWithString () : array
129
    {
130
        return $this->_stringResult;
131
    }
132
133
    public function getResultAsInternalKey () : array
134
    {
135
        return $this->_Result;
136
    }
137
138 1
    public function getStats () {
139 1
        return $this->_Stats;
140
    }
141
142 2
    public function getWinner () {
143 2
        return Condorcet::format($this[1],false,false);
144
    }
145
146 2
    public function getLoser () {
147 2
        return Condorcet::format($this[count($this)],false,false);
148
    }
149
150
    public function getCondorcetWinner () {
151
        return $this->_CondorcetWinner;
152
    }
153
154
    public function getCondorcetLoser () {
155
        return $this->_CondorcetLoser;
156
    }
157
158 4
    protected function makeUserResult (Election $election) : array
159
    {
160 4
        $userResult = [];
161
162 4
        foreach ( $this->_Result as $key => $value ) :
163 4
            if (is_array($value)) :
164 4
                foreach ($value as $candidate_key) :
165 4
                    $userResult[$key][] = $election->getCandidateId($candidate_key);
166
                endforeach;
167 2
            elseif (is_null($value)) :
168
                $userResult[$key] = null;
169
            else :
170 4
                $userResult[$key][] = $election->getCandidateId($value);
171
            endif;
172
        endforeach;
173
174 4
        foreach ( $userResult as $key => $value ) :
175 4
            if (is_null($value)) :
176 4
                $userResult[$key] = null;
177
            endif;
178
        endforeach;
179
180 4
        return $userResult;
181
    }
182
183
184
/////////// Get & Set MetaData ///////////
185
186
    public function addWarning (int $type, string $msg = null) : bool
187
    {
188
        $this->_warning[] = ['type' => $type, 'msg' => $msg];
189
190
        return true;
191
    }
192
193 1
    public function getWarning ($type = null) : array
194
    {
195 1
        if ($type === null) :
196
            return $this->_warning;
197
        else :
198 1
            $r = [];
199
200 1
            foreach ($this->_warning as $oneWarning) :
201
                if ($oneWarning['type'] === (int) $type) :
202
                    $r[] = $oneWarning;
203
                endif;
204
            endforeach;
205
206 1
            return $r;
207
        endif;
208
    }
209
210
    public function getClassGenerator () : string {
211
        return $this->_byClass;
212
    }
213
214
    public function getMethod () : string {
215
        return $this->_fromMethod;
216
    }
217
218
    public function getBuildTimeStamp () : float {
219
        return (float) $this->_BuildTimeStamp;
220
    }
221
222
    public function getCondorcetElectionGeneratorVersion () : string {
223
        return $this->_ElectionCondorcetVersion;
224
    }
225
226
}
227