Passed
Push — dev-1.6.x ( 95af89...c638bc )
by Boudry
04:31
created

CandidatesManager::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 CandidatesManager
19
{
20
    // Data and global options
21
    protected $_Candidates = []; // Candidate list
22
    protected $_i_CandidateId = 'A';
23
24
25
    // Add a vote candidate before voting
26 106
    public function addCandidate ($candidate_id = null) : Candidate
27
    {
28
        // only if the vote has not started
29 106
        if ( $this->_State > 1 ) :
1 ignored issue
show
Bug introduced by
The property _State does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
30
            throw new CondorcetException(2);
31
        endif;
32
33
        // Filter
34 106
        if ( is_bool($candidate_id) || is_array($candidate_id) || (is_object($candidate_id) && !($candidate_id instanceof Candidate)) ) :
35
            throw new CondorcetException(1, $candidate_id);
36
        endif;
37
38
39
        // Process
40 106
        if ( empty($candidate_id) ) :
41 5
            while ( !$this->canAddCandidate($this->_i_CandidateId) ) :
42 5
                $this->_i_CandidateId++;
43
            endwhile;
44
45 5
            $newCandidate = new Candidate($this->_i_CandidateId);
46
        else : // Try to add the candidate_id
47 103
            $newCandidate = ($candidate_id instanceof Candidate) ? $candidate_id : new Candidate ((string) $candidate_id);
48
49 103
            if ( !$this->canAddCandidate($newCandidate) ) :
50
                throw new CondorcetException(3,$candidate_id);
51
            endif;
52
        endif;
53
54
        // Register it
55 106
        $this->_Candidates[] = $newCandidate;
56
57
        // Linking
58 106
        $newCandidate->registerLink($this);
59
60
        // Disallow other candidate object name matching 
61 106
        $newCandidate->setProvisionalState(false);
62
63 106
        return $newCandidate;
64
    }
65
66 106
    public function canAddCandidate ($candidate_id) : bool
67
    {
68 106
        return !$this->existCandidateId($candidate_id, false);
69
    }
70
71
72
    // Destroy a register vote candidate before voting
73 3
    public function removeCandidate ($list) : array
74
    {
75
        // only if the vote has not started
76 3
        if ( $this->_State > 1 ) :
77
            throw new CondorcetException(2);
78
        endif;
79
        
80 3
        if ( !is_array($list) ) :
81 3
            $list = [$list];
82
        endif;
83
84 3
        foreach ($list as &$candidate_id) :
85 3
            $candidate_key = $this->getCandidateKey($candidate_id);
86
87 3
            if ( $candidate_key === false ) :
88
                throw new CondorcetException(4,$candidate_id);
89
            endif;
90
91 3
            $candidate_id = $candidate_key;
92
        endforeach;
93
94 3
        $rem = [];
95 3
        foreach ($list as $candidate_key) :
96 3
            $this->_Candidates[$candidate_key]->destroyLink($this);
97
98 3
            $rem[] = $this->_Candidates[$candidate_key];
99
100 3
            unset($this->_Candidates[$candidate_key]);
101
        endforeach;
102
103 3
        return $rem;
104
    }
105
106
107 1
    public function jsonCandidates (string $input)
108
    {
109 1
        $input = CondorcetUtil::prepareJson($input);
110 1
        if ($input === false) :
111
            return $input;
112
        endif;
113
114
            //////
115
116 1
        $adding = [];
117 1
        foreach ($input as $candidate) :
118
            try {
119 1
                $adding[] = $this->addCandidate($candidate);
120
            }
121 1
            catch (CondorcetException $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
122
        endforeach;
123
124 1
        return $adding;
125
    }
126
127 7
    public function parseCandidates (string $input, bool $allowFile = true)
128
    {
129 7
        $input = CondorcetUtil::prepareParse($input, $allowFile);
130 7
        if ($input === false) :
131
            return $input;
132
        endif;
133
134 7
        $adding = [];
135 7
        foreach ($input as $line) :
136
            // Empty Line
137 7
            if (empty($line)) :
138 1
                continue;
139
            endif;
140
141
            // addCandidate
142
            try {
143 7
                if (self::$_maxParseIteration !== null && count($adding) >= self::$_maxParseIteration) :
144
                    throw new CondorcetException(12, self::$_maxParseIteration);
145
                endif;
146
147 7
                $adding[] = $this->addCandidate($line);
148
            } catch (CondorcetException $e) {
149
                if ($e->getCode() === 12)
150 7
                    {throw $e;}
151
            }
152
        endforeach;
153
154 7
        return $adding;
155
    }
156
157
158
    //:: CANDIDATES TOOLS :://
159
160
    // Count registered candidates
161 87
    public function countCandidates () : int
162
    {
163 87
        return count($this->_Candidates);
164
    }
165
166
    // Get the list of registered CANDIDATES
167 88
    public function getCandidatesList (bool $stringMode = false) : array
168
    {
169 88
        if (!$stringMode) :
170 86
            return $this->_Candidates;
171
        else :
172 4
            $result = [];
173
174 4
            foreach ($this->_Candidates as $candidateKey => &$oneCandidate) :
175 4
                $result[$candidateKey] = $oneCandidate->getName();
176
            endforeach;
177
178 4
            return $result;
179
        endif;
180
    }
181
182 93
    public function getCandidateKey ($candidate_id)
183
    {
184 93
        if ($candidate_id instanceof Candidate) :
185 80
            return array_search($candidate_id, $this->_Candidates, true);
186
        else:
187 91
            return array_search(trim((string) $candidate_id), $this->_Candidates, false);
188
        endif;
189
    }
190
191 77
    public function getCandidateId (int $candidate_key, bool $onlyName = false)
192
    {
193 77
        if (!array_key_exists($candidate_key, $this->_Candidates)) :
194
            return false;
195
        else :
196 77
            return ($onlyName) ? $this->_Candidates[$candidate_key]->getName() : $this->_Candidates[$candidate_key];
197
        endif;
198
    }
199
200 106
    public function existCandidateId ($candidate_id, bool $strict = true) : bool
201
    {
202 106
        return ($strict) ? in_array($candidate_id, $this->_Candidates, true) : in_array((string) $candidate_id, $this->_Candidates);
203
    }
204
205 3
    public function getCandidateObjectByName (string $s)
206
    {
207 3
        foreach ($this->_Candidates as $oneCandidate) :
208
209 3
            if ($oneCandidate->getName() === $s) :
210 3
                return $oneCandidate;
211
            endif;
212
        endforeach;
213
214 1
        return false;
215
    }
216
217
}
218