Passed
Push — master ( 88b497...e86a88 )
by Boudry
03:07
created

Election::addCandidate()   D

Complexity

Conditions 10
Paths 8

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 10.6591

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 13
cts 16
cp 0.8125
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 22
nc 8
nop 1
crap 10.6591

1 Method

Rating   Name   Duplication   Size   Complexity  
A Election::setStateToVote() 0 16 4

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 27 and the first side effect is on line 109.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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\Condorcet;
13
use Condorcet\CondorcetException;
14
use Condorcet\CondorcetVersion;
15
use Condorcet\Result;
16
use Condorcet\Vote;
17
use Condorcet\DataManager\VotesManager;
18
use Condorcet\DataManager\DataHandlerDrivers\DataHandlerDriverInterface;
19
use Condorcet\ElectionProcess\CandidatesProcess;
20
use Condorcet\ElectionProcess\ResultsProcess;
21
use Condorcet\ElectionProcess\VotesProcess;
22
use Condorcet\ElectionProcess\VoteUtil;
23
use Condorcet\Timer\Manager as Timer_Manager;
24
25
26
// Base Condorcet class
27
class Election
28
{
29
30
/////////// PROPERTIES ///////////
31
32
    public const MAX_LENGTH_CANDIDATE_ID = 30; // Max length for candidate identifiant string
33
34
    protected static $_maxParseIteration = null;
35
    protected static $_maxVoteNumber = null;
36
    protected static $_checksumMode = false;
37
38
/////////// STATICS METHODS ///////////
39
40
    // Change max parse iteration
41 1
    public static function setMaxParseIteration (?int $value) : ?int
42
    {
43 1
        self::$_maxParseIteration = $value;
44 1
        return self::$_maxParseIteration;
45
    }
46
47
    // Change max vote number
48 1
    public static function setMaxVoteNumber (?int $value) : ?int
49
    {
50 1
        self::$_maxVoteNumber = $value;
51 1
        return self::$_maxVoteNumber;
52
    }
53
54
55
/////////// CONSTRUCTOR ///////////
56
57
    use CondorcetVersion;
58
59
    // Mechanics
60
    protected $_State = 1; // 1 = Add Candidates / 2 = Voting / 3 = Some result have been computing
61
    protected $_timer;
62
63
    // Params
64
    protected $_ImplicitRanking = true;
65
    protected $_VoteWeightRule = false;
66
67
        //////
68
69 111
    public function __construct ()
70
    {
71 111
        $this->_Candidates = [];
72 111
        $this->_Votes = new VotesManager ($this);
73 111
        $this->_timer = new Timer_Manager;
74 111
    }
75
76 1
    public function __destruct ()
77
    {
78 1
        $this->destroyAllLink();
79 1
    }
80
81 2
    public function __sleep () : array
82
    {
83
        // Don't include others data
84
        $include = [
85 2
            '_Candidates',
86
            '_Votes',
87
88
            '_i_CandidateId',
89
            '_State',
90
            '_objectVersion',
91
            '_ignoreStaticMaxVote',
92
93
            '_ImplicitRanking',
94
            '_VoteWeightRule',
95
96
            '_Pairwise',
97
            '_Calculator',
98
        ];
99
100 2
        !self::$_checksumMode && array_push($include, '_timer');
101
102 2
        return $include;
103
    }
104
105 1
    public function __wakeup ()
106
    {
107 1
        if ( version_compare($this->getObjectVersion('MAJOR'),Condorcet::getVersion('MAJOR'),'!=') ) :
108
            throw new CondorcetException(11, 'Your object version is '.$this->getObjectVersion().' but the class engine version is '.Condorcet::getVersion('ENV'));
109
        endif;
110 1
    }
111
112 1
    public function __clone ()
113
    {
114 1
        $this->_Votes = clone $this->_Votes;
115 1
        $this->_Votes->setElection($this);      
116 1
        $this->registerAllLinks();
117
118 1
        $this->_timer = clone $this->_timer;
119
120 1
        if ($this->_Pairwise !== null) :
121 1
            $this->_Pairwise = clone $this->_Pairwise;
122 1
            $this->_Pairwise->setElection($this);
123
        endif;
124 1
    }
125
126
127
/////////// TIMER & CHECKSUM ///////////
128
129 2
    public function getGlobalTimer (bool $float = false) {
130 2
        return $this->_timer->getGlobalTimer($float);
131
    }
132
133 2
    public function getLastTimer (bool $float = false) {
134 2
        return $this->_timer->getLastTimer($float);
135
    }
136
137 80
    public function getTimerManager () : Timer_Manager {
138 80
        return $this->_timer;
139
    }
140
141 1
    public function getChecksum () : string
142
    {
143 1
        self::$_checksumMode = true;
144
145 1
        $r = hash_init('sha256');
146
147 1
        foreach ($this->_Candidates as $value) :
148 1
            hash_update($r, (string) $value);
149
        endforeach;
150
151 1
        foreach ($this->_Votes as $value) :
152 1
            hash_update($r, (string) $value);
153
        endforeach;
154
155 1
        $this->_Pairwise !== null
156 1
            && hash_update($r,serialize($this->_Pairwise->getExplicitPairwise()));
157
158 1
        hash_update($r, $this->getObjectVersion('major'));
159
160 1
        self::$_checksumMode = false;
161
162 1
        return hash_final($r);
163
    }
164
165
166
/////////// LINKS REGULATION ///////////
167
168 1
    protected function registerAllLinks () : void
169
    {
170 1
        foreach ($this->_Candidates as $value) :
171 1
            $value->registerLink($this);
172
        endforeach;
173
174 1
        if ($this->_State > 1) :
175 1
            foreach ($this->_Votes as $value) :
176 1
                $value->registerLink($this);
177
            endforeach;
178
        endif;
179 1
    }
180
181 1
    protected function destroyAllLink () : void
182
    {
183 1
        foreach ($this->_Candidates as $value) :
184 1
            $value->destroyLink($this);
185
        endforeach;
186
187 1
        if ($this->_State > 1) :
188 1
            foreach ($this->_Votes as $value) :
189 1
                $value->destroyLink($this);
190
            endforeach;
191
        endif;
192 1
    }
193
194
195
  /////////// IMPLICIT RANKING & VOTE WEIGHT ///////////
196
197 86
    public function getImplicitRankingRule () : bool
198
    {
199 86
        return $this->_ImplicitRanking;
200
    }
201
202 3
    public function setImplicitRanking (bool $rule = true) : bool
203
    {
204 3
        $this->_ImplicitRanking = $rule;
205 3
        $this->cleanupResult();
206 3
        return $this->getImplicitRankingRule();
207
    }
208
209 82
    public function isVoteWeightIsAllowed () : bool
210
    {
211 82
        return $this->_VoteWeightRule;
212
    }
213
214 1
    public function allowVoteWeight (bool $rule = true) : bool
215
    {
216 1
        $this->_VoteWeightRule = $rule;
217 1
        $this->cleanupResult();
218 1
        return $this->isVoteWeightIsAllowed();
219
    }
220
221
222
/////////// LARGE ELECTION MODE ///////////
223
224 3
    public function setExternalDataHandler (DataHandlerDriverInterface $driver) : bool
225
    {
226 3
        if (!$this->_Votes->isUsingHandler()) :
227 3
            $this->_Votes->importHandler($driver);
228 3
            return true;
229
        else :
230
            throw new CondorcetException(24);
231
        endif;
232
    }
233
234 1
    public function removeExternalDataHandler () : bool
235
    {
236 1
        if ($this->_Votes->isUsingHandler()) :
237 1
            $this->_Votes->closeHandler();
238 1
            return true;
239
        else :
240
            throw new CondorcetException(23);
241
        endif;
242
    }
243
244
245
/////////// STATE ///////////
246
247
    // Close the candidate config, be ready for voting (optional)
248 98
    public function setStateToVote () : bool
249
    {
250 98
        if ( $this->_State === 1 ) :
251 98
                if (empty($this->_Candidates)) :
252
                    throw new CondorcetException(20);
253
                endif;
254
255 98
                $this->_State = 2;
256
257
        // If voting continues after a first set of results
258 86
        elseif ( $this->_State > 2 ) :
259 5
                $this->cleanupResult();
260
        endif;
261
262 98
        return true;
263
    }
264
265
    // Prepare to compute results & caching system
266 80
    protected function prepareResult () : bool
267
    {
268 80
        if ($this->_State > 2) :
269 74
            return false;
270 80
        elseif ($this->_State === 2) :
271 80
            $this->cleanupResult();
272
273
            // Do Pairewise
274 80
            $this->makePairwise();
275
276
            // Change state to result
277 80
            $this->_State = 3;
278
279
            // Return
280 80
            return true;
281
        else :
282
            throw new CondorcetException(6);
283
        endif;
284
    }
285
286
287
/////////// CANDIDATES ///////////
288
289
    use CandidatesProcess;
290
291
292
/////////// VOTING ///////////
293
294
    use VotesProcess;
295
296
297
/////////// RESULTS ///////////
298
299
    use ResultsProcess;
300
301
}
302