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

CandidatesProcess::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

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
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\ElectionProcess;
11
12
use Condorcet\Candidate;
13
use Condorcet\CondorcetException;
14
use Condorcet\CondorcetUtil;
15
16
17
// Manage Candidates for Election class
18
trait CandidatesProcess
19
{
20
21
/////////// CONSTRUCTOR ///////////
22
23
    // Data and global options
24
    protected $_Candidates = []; // Candidate list
25
    protected $_i_CandidateId = 'A';
26
27
28
/////////// GET CANDIDATES ///////////
29
30
    // Count registered candidates
31 87
    public function countCandidates () : int
32
    {
33 87
        return count($this->_Candidates);
34
    }
35
36
    // Get the list of registered CANDIDATES
37 88
    public function getCandidatesList (bool $stringMode = false) : array
38
    {
39 88
        if (!$stringMode) :
40 86
            return $this->_Candidates;
41
        else :
42 4
            $result = [];
43
44 4
            foreach ($this->_Candidates as $candidateKey => &$oneCandidate) :
45 4
                $result[$candidateKey] = $oneCandidate->getName();
46
            endforeach;
47
48 4
            return $result;
49
        endif;
50
    }
51
52 93
    public function getCandidateKey ($candidate_id)
53
    {
54 93
        if ($candidate_id instanceof Candidate) :
55 80
            return array_search($candidate_id, $this->_Candidates, true);
56
        else:
57 91
            return array_search(trim((string) $candidate_id), $this->_Candidates, false);
58
        endif;
59
    }
60
61 77
    public function getCandidateId (int $candidate_key, bool $onlyName = false)
62
    {
63 77
        if (!array_key_exists($candidate_key, $this->_Candidates)) :
64
            return false;
65
        else :
66 77
            return ($onlyName) ? $this->_Candidates[$candidate_key]->getName() : $this->_Candidates[$candidate_key];
67
        endif;
68
    }
69
70 106
    public function existCandidateId ($candidate_id, bool $strict = true) : bool
71
    {
72 106
        return ($strict) ? in_array($candidate_id, $this->_Candidates, true) : in_array((string) $candidate_id, $this->_Candidates);
73
    }
74
75 3
    public function getCandidateObjectByName (string $s)
76
    {
77 3
        foreach ($this->_Candidates as $oneCandidate) :
78
79 3
            if ($oneCandidate->getName() === $s) :
80 3
                return $oneCandidate;
81
            endif;
82
        endforeach;
83
84 1
        return false;
85
    }
86
87
88
/////////// ADD & REMOVE CANDIDATE ///////////
89
90
    // Add a vote candidate before voting
91 106
    public function addCandidate ($candidate_id = null) : Candidate
92
    {
93
        // only if the vote has not started
94 106
        if ( $this->_State > 1 ) :
95
            throw new CondorcetException(2);
96
        endif;
97
98
        // Filter
99 106
        if ( is_bool($candidate_id) || is_array($candidate_id) || (is_object($candidate_id) && !($candidate_id instanceof Candidate)) ) :
100
            throw new CondorcetException(1, $candidate_id);
101
        endif;
102
103
104
        // Process
105 106
        if ( empty($candidate_id) ) :
106 5
            while ( !$this->canAddCandidate($this->_i_CandidateId) ) :
107 5
                $this->_i_CandidateId++;
108
            endwhile;
109
110 5
            $newCandidate = new Candidate($this->_i_CandidateId);
111
        else : // Try to add the candidate_id
112 103
            $newCandidate = ($candidate_id instanceof Candidate) ? $candidate_id : new Candidate ((string) $candidate_id);
113
114 103
            if ( !$this->canAddCandidate($newCandidate) ) :
115
                throw new CondorcetException(3,$candidate_id);
116
            endif;
117
        endif;
118
119
        // Register it
120 106
        $this->_Candidates[] = $newCandidate;
121
122
        // Linking
123 106
        $newCandidate->registerLink($this);
124
125
        // Disallow other candidate object name matching 
126 106
        $newCandidate->setProvisionalState(false);
127
128 106
        return $newCandidate;
129
    }
130
131 106
    public function canAddCandidate ($candidate_id) : bool
132
    {
133 106
        return !$this->existCandidateId($candidate_id, false);
134
    }
135
136
    // Destroy a register vote candidate before voting
137 3
    public function removeCandidate ($list) : array
138
    {
139
        // only if the vote has not started
140 3
        if ( $this->_State > 1 ) :
141
            throw new CondorcetException(2);
142
        endif;
143
        
144 3
        if ( !is_array($list) ) :
145 3
            $list = [$list];
146
        endif;
147
148 3
        foreach ($list as &$candidate_id) :
149 3
            $candidate_key = $this->getCandidateKey($candidate_id);
150
151 3
            if ( $candidate_key === false ) :
152
                throw new CondorcetException(4,$candidate_id);
153
            endif;
154
155 3
            $candidate_id = $candidate_key;
156
        endforeach;
157
158 3
        $rem = [];
159 3
        foreach ($list as $candidate_key) :
160 3
            $this->_Candidates[$candidate_key]->destroyLink($this);
161
162 3
            $rem[] = $this->_Candidates[$candidate_key];
163
164 3
            unset($this->_Candidates[$candidate_key]);
165
        endforeach;
166
167 3
        return $rem;
168
    }
169
170
171
/////////// PARSE CANDIDATES ///////////
172
173 1
    public function jsonCandidates (string $input)
174
    {
175 1
        $input = CondorcetUtil::prepareJson($input);
176 1
        if ($input === false) :
177
            return $input;
178
        endif;
179
180
            //////
181
182 1
        $adding = [];
183 1
        foreach ($input as $candidate) :
184
            try {
185 1
                $adding[] = $this->addCandidate($candidate);
186
            }
187 1
            catch (CondorcetException $e) {
188
                // Ignore invalid vote
189
            }
190
        endforeach;
191
192 1
        return $adding;
193
    }
194
195 7
    public function parseCandidates (string $input, bool $allowFile = true)
196
    {
197 7
        $input = CondorcetUtil::prepareParse($input, $allowFile);
198 7
        if ($input === false) :
199
            return $input;
200
        endif;
201
202 7
        $adding = [];
203 7
        foreach ($input as $line) :
204
            // Empty Line
205 7
            if (empty($line)) :
206 1
                continue;
207
            endif;
208
209
            // addCandidate
210
            try {
211 7 View Code Duplication
                if (self::$_maxParseIteration !== null && count($adding) >= self::$_maxParseIteration) :
212
                    throw new CondorcetException(12, self::$_maxParseIteration);
213
                endif;
214
215 7
                $adding[] = $this->addCandidate($line);
216
            } catch (CondorcetException $e) {
217
                if ($e->getCode() === 12)
218 7
                    {throw $e;}
219
            }
220
        endforeach;
221
222 7
        return $adding;
223
    }
224
225
}
226