Completed
Branch dev-2.0 (210bc7)
by Boudry
06:33
created

VotesManager::setElection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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