Passed
Push — TEST/ScrutinizerPHPAnalysisEng... ( c9e065...573acf )
by Boudry
09:25
created

Election::parseCandidates()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 9.214

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 11
cts 15
cp 0.7332
rs 5.3846
c 0
b 0
f 0
cc 8
crap 9.214
eloc 19
nc 10
nop 2
1
<?php
1 ignored issue
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 28 and the first side effect is on line 110.

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