CandidatesProcess::getCandidateObjectFromKey()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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