VotesManager::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
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\DataManager;
12
13
use CondorcetPHP\Condorcet\{Election, Vote};
14
use CondorcetPHP\Condorcet\Throwable\CondorcetException;
15
16
class VotesManager extends ArrayManager
17
{
18
19
/////////// Magic ///////////
20
21 158
    public function __construct (Election $election)
22
    {
23 158
        $this->setElection($election);
24
25 158
        parent::__construct();
26 158
    }
27
28 158
    public function setElection (Election $election) : void
29
    {
30 158
        $this->_link[0] = $election;
31 158
    }
32
33 98
    public function getElection () : Election
34
    {
35 98
        return $this->_link[0];
36
    }
37
38
/////////// Data CallBack for external drivers ///////////
39
40 8
    public function getDataContextObject () : DataContextInterface
41
    {
42
        $context = new Class implements DataContextInterface {
43
            public $election;
44
45 5
            public function dataCallBack ($data) : Vote
46
            {
47 5
                $vote = new Vote ($data);
48 5
                $this->election->checkVoteCandidate($vote);
49 5
                $vote->registerLink($this->election);
50
51 5
                return $vote;
52
            }
53
54 6
            public function dataPrepareStoringAndFormat ($data) : string
55
            {
56 6
                $data->destroyLink($this->election);
57
58 6
                return (string) $data;
59
            }
60
        };
61
62 8
        $context->election = $this->_link[0] ?? null;
63
64 8
        return $context;
65
    }
66
67 12
    protected function preDeletedTask ($object) : void
68
    {
69 12
        $object->destroyLink($this->_link[0]);
70 12
    }
71
72
/////////// Array Access - Specials improvements ///////////
73
74 131
    public function offsetSet($offset, $value) : void
75
    {
76 131
        if ($value instanceof Vote) :
77 131
            parent::offsetSet($offset,$value);
78 131
            $this->UpdateAndResetComputing($this->_maxKey,1);
79
        else :
80 1
            throw new CondorcetException (0,'Value must be an instanceof CondorcetPHP\Vote');
81
        endif;
82 131
    }
83
84 8
    public function offsetUnset($offset) : void
85
    {
86
        // $this->setStateToVote();
87 8
        $this->UpdateAndResetComputing($offset,2);
88 8
        parent::offsetUnset($offset);
89 8
    }
90
91
/////////// Internal Election related methods ///////////
92
93 131
    public function UpdateAndResetComputing (int $key, int $type) : void
94
    {
95 131
        foreach ($this->_link as $election) :
96 131
            if ($election->getState() === 3) :
97
98 7
                if ($type === 1) :
99 6
                    $election->getPairwise()->addNewVote($key);
100 4
                elseif ($type === 2) :
101 4
                    $election->getPairwise()->removeVotes($key);
102
                endif;
103
104 7
                $election->cleanupCalculator();
105
            else :
106 131
                $election->setStateToVote();
107
            endif;
108
109
        endforeach;
110 131
    }
111
112
    protected function setStateToVote () : void
113
    {
114
        foreach ($this->_link as $election) :
115
            $election->setStateToVote();
116
        endforeach;
117
    }
118
119
/////////// Get Votes Methods ///////////
120
121 10
    public function getVoteKey (Vote $vote) : ?int
122
    {
123 10
        ($r = array_search($vote, $this->_Container, true)) !== false || ($r = array_search($vote, $this->_Cache, true));
124
125 10
        return ($r !== false) ? $r : null;
126
    }
127
128 2
    protected function getFullVotesListGenerator () : \Generator
129
    {
130 2
        foreach ($this as $voteKey => $vote) :
131 2
            yield $voteKey => $vote;
132
        endforeach;
133 2
    }
134
135 9
    protected function getPartialVotesListGenerator (array $tag, bool $with) : \Generator
136
    {
137 9
        foreach ($this as $voteKey => $vote) :
138 9
            $noOne = true;
139 9
            foreach ($tag as $oneTag) :
140 9
                if ( ( $oneTag === $voteKey ) || in_array($oneTag, $vote->getTags(),true) ) :
141 9
                    if ($with) :
142 9
                        yield $voteKey => $vote;
143 8
                        break;
144
                    else :
145 9
                        $noOne = false;
146
                    endif;
147
                endif;
148
            endforeach;
149
150 9
            if (!$with && $noOne) :
151 9
                yield $voteKey => $vote;
152
            endif;
153
        endforeach;
154 8
    }
155
156
    // Get the votes list
157 16
    public function getVotesList ($tag = null, bool $with = true) : array
158
    {
159 16
        if ($tag === null) :
160 14
            return $this->getFullDataSet();
161
        else :
162 7
            $search = [];
163
164 7
            foreach ($this->getPartialVotesListGenerator($tag,$with) as $voteKey => $vote) :
165 7
                $search[$voteKey] = $vote;
166
            endforeach;
167
168 7
            return $search;
169
        endif;
170
    }
171
172
    // Get the votes list as a generator object
173 3
    public function getVotesListGenerator ($tag = null, bool $with = true) : \Generator
174
    {
175 3
        if ($tag === null) :
176 2
            return $this->getFullVotesListGenerator();
177
        else :
178 3
            return $this->getPartialVotesListGenerator($tag,$with);
179
        endif;
180
    }
181
182 95
    public function getVotesValidUnderConstraintGenerator () : \Generator
183
    {
184 95
        foreach ($this as $voteKey => $oneVote) :
185 95
            if (!$this->getElection()->testIfVoteIsValidUnderElectionConstraints($oneVote)) :
186 1
                continue;
187
            endif;
188
189 95
            yield $voteKey => $oneVote;
190
        endforeach;
191 95
    }
192
193 5
    public function getVotesListAsString () : string
194
    {
195 5
        $simpleList = '';
196
197 5
        $weight = [];
198 5
        $nb = [];
199
200 5
        foreach ($this as $oneVote) :
201 5
            $oneVoteString = $oneVote->getSimpleRanking($this->_link[0]);
202
203 5
            if(!array_key_exists($oneVoteString, $weight)) :
204 5
                $weight[$oneVoteString] = 0;
205
            endif;
206 5
            if(!array_key_exists($oneVoteString, $nb)) :
207 5
                $nb[$oneVoteString] = 0;
208
            endif;
209
210 5
            if ($this->getElection()->isVoteWeightAllowed()) :
211 1
                $weight[$oneVoteString] += $oneVote->getWeight();
212
            else :
213 4
                $weight[$oneVoteString]++;
214
            endif;
215
216 5
            $nb[$oneVoteString]++;
217
        endforeach;
218
219 5
        ksort($weight);
220 5
        arsort($weight);
221
222 5
        $isFirst = true;
223 5
        foreach ($weight as $key => $value) :
224 5
            if (!$isFirst) :
225 5
                $simpleList .= "\n";
226
            endif;
227 5
            $voteString = ($key === '') ? '{{EMPTY_VOTE_IN_CONTEXT}}' : $key;
228 5
            $simpleList .= $voteString.' * '.$nb[$key];
229 5
            $isFirst = false;
230
        endforeach;
231
232 5
        return $simpleList;
233
    }
234
235 12
    public function countVotes (?array $tag, bool $with) : int
236
    {
237 12
        if ($tag === null) :
238 9
            return count($this);
239
        else :
240 5
            $count = 0;
241
242 5
            foreach ($this as $key => $value) :
243 5
                $noOne = true;
244 5
                foreach ($tag as $oneTag) :
245 5
                    if ( ( $oneTag === $key ) || in_array($oneTag, $value->getTags(),true) ) :
246 5
                        if ($with) :
247 5
                            $count++;
248 5
                            break;
249
                        else :
250 5
                            $noOne = false;
251
                        endif;
252
                    endif;
253
                endforeach;
254
255 5
                if (!$with && $noOne) :
256 5
                    $count++;
257
                endif;
258
            endforeach;
259
260 5
            return $count;
261
        endif;
262
    }
263
264 1
    public function countInvalidVoteWithConstraints () : int
265
    {
266 1
        $count = 0;
267
268 1
        foreach ($this as $oneVote) :
269 1
            if(!$this->getElection()->testIfVoteIsValidUnderElectionConstraints($oneVote)) :
270 1
                $count++;
271
            endif;
272
        endforeach;
273
274 1
        return $count;
275
    }
276
277 7
    public function sumVotesWeight (bool $constraint = false) : int
278
    {
279 7
        $sum = 0;
280
281 7
        foreach ($this as $oneVote) :
282 7
            if ( !$constraint || $this->getElection()->testIfVoteIsValidUnderElectionConstraints($oneVote) ) :
283 7
                $sum += $this->getElection()->isVoteWeightAllowed() ? $oneVote->getWeight() : 1;
284
            endif;
285
        endforeach;
286
287 7
        return $sum;
288
    }
289
}
290