Passed
Branch dev-1.8.x (af6e5a)
by Boudry
03:20
created

CandidatesProcess::getCandidatesList()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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