Passed
Branch dev-2.0 (faa14c)
by Boudry
02:42
created

ResultsProcess::getExplicitPairwise()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
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\ElectionProcess;
12
13
use CondorcetPHP\Condorcet\Condorcet;
14
use CondorcetPHP\Condorcet\CondorcetException;
15
use CondorcetPHP\Condorcet\Result;
16
use CondorcetPHP\Condorcet\Algo\Pairwise;
17
use CondorcetPHP\Condorcet\Timer\Chrono as Timer_Chrono;
18
19
// Manage Results for Election class
20
trait ResultsProcess
21
{
22
23
/////////// CONSTRUCTOR ///////////
24
25
    // Result
26
    protected $_Pairwise;
27
    protected $_Calculator;
28
29
30
/////////// GET RESULTS ///////////
31
32
    // Generic function for default result with ability to change default object method
33 90
    public function getResult (?string $method = null, array $options = []) : Result
34
    {
35 90
        $options = self::formatResultOptions($options);
36
37
        // Filter if tag is provided & return
38 90
        if ($options['%tagFilter']) :
39 2
            $chrono = new Timer_Chrono ($this->_timer, 'GetResult with filter');
40
41 2
            $filter = new self;
42
43 2
            foreach ($this->getCandidatesList() as $candidate) :
44 2
                $filter->addCandidate($candidate);
45
            endforeach;
46
47 2
            foreach ($this->getVotesList($options['tags'], $options['withTag']) as $vote) :
48 2
                $filter->addVote($vote);
49
            endforeach;
50
51 2
            unset($chrono);
52
53 2
            return $filter->getResult($method);
54
        endif;
55
56
            ////// Start //////
57
58
        // Prepare
59 90
        $this->prepareResult();
60
61
            //////
62
63 89
        $chrono = new Timer_Chrono ($this->_timer);
64
65 89
        if ($method === null) :
66 7
            $this->initResult(Condorcet::getDefaultMethod());
67 7
            $result = $this->_Calculator[Condorcet::getDefaultMethod()]->getResult();
68 85
        elseif ($method = Condorcet::isAuthMethod((string) $method)) :
69 85
            $this->initResult($method);
70 83
            $result = $this->_Calculator[$method]->getResult();
71
        else :
72
            throw new CondorcetException(8,$method);
73
        endif;
74
75 86
        $chrono->setRole('GetResult for '.$method);
76
77 86
        return $result;
78
    }
79
80
81 92
    public function getWinner (?string $substitution = null)
82
    {
83 92
        $algo = Condorcet::condorcetBasicSubstitution($substitution);
84
85
            //////
86
87 92
        if ($algo === Condorcet::CONDORCET_BASIC_CLASS) :
88 90
            new Timer_Chrono ($this->_timer, 'GetWinner for CondorcetBasic');
89 90
            $this->initResult($algo);
90 90
            $result = $this->_Calculator[$algo]->getWinner();
91
92 90
            return ($result === null) ? null : $this->getCandidateObjectFromKey($result);
0 ignored issues
show
Bug introduced by
It seems like getCandidateObjectFromKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
93
        else :
94 51
            return $this->getResult($algo)->getWinner();
95
        endif;
96
    }
97
98
99 89
    public function getLoser (?string $substitution = null)
100
    {
101 89
        $algo = Condorcet::condorcetBasicSubstitution($substitution);
102
103
            //////
104
105 89
        if ($algo === Condorcet::CONDORCET_BASIC_CLASS) :
106 89
            new Timer_Chrono ($this->_timer, 'GetLoser for CondorcetBasic');
107 89
            $this->initResult($algo);
108 89
            $result = $this->_Calculator[$algo]->getLoser();
109
110 89
            return ($result === null) ? null : $this->getCandidateObjectFromKey($result);
0 ignored issues
show
Bug introduced by
It seems like getCandidateObjectFromKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
111
        else :
112 2
            return $this->getResult($algo)->getLoser();
113
        endif;
114
    }
115
116 91
    public function getPairwise () : Pairwise
117
    {
118 91
        $this->prepareResult();
0 ignored issues
show
Bug introduced by
It seems like prepareResult() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
119 91
        return $this->_Pairwise;
120
    }
121
122 1
    public function getExplicitPairwise () : array
123
    {
124 1
        return $this->getPairwise()->getExplicitPairwise();
125
    }
126
127
128
129
/////////// MAKE RESULTS ///////////
130
131 1
    public function computeResult (?string $method = null) : void
132
    {
133 1
        $this->getResult($method);
134 1
    }
135
136 94
    protected function makePairwise () : void
137
    {
138 94
        $this->_Pairwise = new Pairwise ($this);
139 94
    }
140
141 94
    protected function initResult (string $class) : void
142
    {
143 94
        if ( !isset($this->_Calculator[$class]) ) :
144 94
            $this->_Calculator[$class] = new $class($this);
145
        endif;
146 92
    }
147
148
    // Cleanup results to compute again with new votes
149 95
    protected function cleanupResult () : void
150
    {
151
        // Reset state
152 95
        if ($this->_State > 2) : 
153 10
            $this->_State = 2;
154
        endif;
155
156
            //////
157
158
        // Clean pairwise
159 95
        $this->_Pairwise = null;
160
161
        // Algos
162 95
        $this->_Calculator = null;
163 95
    }
164
165
166
/////////// UTILS ///////////
167
168 90
    protected static function formatResultOptions (array $arg) : array
169
    {
170
        // About tag filter
171 90
        if (isset($arg['tags'])):
172 2
            $arg['%tagFilter'] = true;
173
174 2
            if ( !isset($arg['withTag']) || !is_bool($arg['withTag']) ) :
175 2
                $arg['withTag'] = true;
176
            endif;
177
        else:
178 90
            $arg['%tagFilter'] = false;
179
        endif;
180
181 90
        return $arg;
182
    }
183
}
184