Completed
Push — dev-1.6.x ( 048fe7...a70c53 )
by Boudry
04:20
created

ResultsProcess::computeResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/*
3
    Condorcet PHP Class, with Schulze Methods and others !
4
5
    By Julien Boudry - MIT LICENSE (Please read LICENSE.txt)
6
    https://github.com/julien-boudry/Condorcet
7
*/
8
declare(strict_types=1);
9
10
namespace Condorcet\ElectionProcess;
11
12
use Condorcet\Condorcet;
13
use Condorcet\CondorcetException;
14
use Condorcet\Result;
15
use Condorcet\Algo\Pairwise;
16
use Condorcet\Timer\Chrono as Timer_Chrono;
17
18
// Manage Results for Election class
19
trait ResultsProcess
20
{
21
22
/////////// CONSTRUCTOR ///////////
23
24
    // Result
25
    protected $_Pairwise;
26
    protected $_Calculator;
27
28
29
/////////// GET RESULTS ///////////
30
31
    // Generic function for default result with ability to change default object method
32 75
    public function getResult ($method = true, array $options = []) : Result
33
    {
34 75
        $options = self::formatResultOptions($options);
35
36
        // Filter if tag is provided & return
37 75
        if ($options['%tagFilter']) :
38 2
            $chrono = new Timer_Chrono ($this->_timer, 'GetResult with filter');
39
40 2
            $filter = new self;
41
42 2
            foreach ($this->getCandidatesList() as $candidate) :
43 2
                $filter->addCandidate($candidate);
44
            endforeach;
45
46 2
            foreach ($this->getVotesList($options['tags'], $options['withTag']) as $vote) :
47 2
                $filter->addVote($vote);
48
            endforeach;
49
50 2
            unset($chrono);
51
52 2
            return $filter->getResult($method);
53
        endif;
54
55
            ////// Start //////
56
57
        // Prepare
58 75
        $this->prepareResult();
1 ignored issue
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...
59
60
            //////
61
62 75
        $chrono = new Timer_Chrono ($this->_timer);
63
64 75
        if ($method === true) :
65 7
            $this->initResult(Condorcet::getDefaultMethod());
66 7
            $result = $this->_Calculator[Condorcet::getDefaultMethod()]->getResult();
67 71
        elseif ($method = Condorcet::isAuthMethod((string) $method)) :
68 71
            $this->initResult($method);
69 69
            $result = $this->_Calculator[$method]->getResult();
70
        else :
71
            throw new CondorcetException(8,$method);
72
        endif;
73
74 72
        $chrono->setRole('GetResult for '.$method);
75
76 72
        return $result;
77
    }
78
79
80 78
    public function getWinner (?string $substitution = null)
81
    {
82 78
        $algo = Condorcet::condorcetBasicSubstitution($substitution);
83
84
            //////
85
86 78
        if ($algo === Condorcet::CONDORCET_BASIC_CLASS) :
87 76
            new Timer_Chrono ($this->_timer, 'GetWinner for CondorcetBasic');
88 76
            $this->initResult($algo);
89 76
            $result = $this->_Calculator[$algo]->getWinner();
90
91 76
            return ($result === null) ? null : $this->getCandidateId($result);
92
        else :
93 50
            return $this->getResult($algo)->getWinner();
94
        endif;
95
    }
96
97
98 75
    public function getLoser (?string $substitution = null)
99
    {
100 75
        $algo = Condorcet::condorcetBasicSubstitution($substitution);
101
102
            //////
103
104 75
        if ($algo === Condorcet::CONDORCET_BASIC_CLASS) :
105 75
            new Timer_Chrono ($this->_timer, 'GetLoser for CondorcetBasic');
106 75
            $this->initResult($algo);
107 75
            $result = $this->_Calculator[$algo]->getLoser();
108
109 75
            return ($result === null) ? null : $this->getCandidateId($result);
110
        else :
111 2
            return $this->getResult($algo)->getLoser();
112
        endif;
113
    }
114
115 77
    public function getPairwise (bool $explicit = true)
116
    {
117 77
        $this->prepareResult();
1 ignored issue
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...
118
119 77
        return (!$explicit) ? $this->_Pairwise : $this->_Pairwise->getExplicitPairwise();
120
    }
121
122
123
/////////// MAKE RESULTS ///////////
124
125 1
    public function computeResult ($method = true) : void
126
    {
127 1
        $this->getResult($method);
128 1
    }
129
130 80
    protected function makePairwise () : void
131
    {
132 80
        $this->_Pairwise = new Pairwise ($this);
133 80
    }
134
135 80
    protected function initResult (string $class) : void
136
    {
137 80
        if ( !isset($this->_Calculator[$class]) ) :
138 80
            $this->_Calculator[$class] = new $class($this);
139
        endif;
140 78
    }
141
142
    // Cleanup results to compute again with new votes
143 80
    protected function cleanupResult () : void
144
    {
145
        // Reset state
146 80
        if ($this->_State > 2) : 
147 7
            $this->_State = 2;
1 ignored issue
show
Bug introduced by
The property _State does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
148
        endif;
149
150
            //////
151
152
        // Clean pairwise
153 80
        $this->_Pairwise = null;
154
155
        // Algos
156 80
        $this->_Calculator = null;
157 80
    }
158
159
160
/////////// UTILS ///////////
161
162 75
    protected static function formatResultOptions (array $arg) : array
163
    {
164
        // About tag filter
165 75
        if (isset($arg['tags'])):
166 2
            $arg['%tagFilter'] = true;
167
168 2
            if ( !isset($arg['withTag']) || !is_bool($arg['withTag']) ) :
169 2
                $arg['withTag'] = true;
170
            endif;
171
        else:
172 75
            $arg['%tagFilter'] = false;
173
        endif;
174
175 75
        return $arg;
176
    }
177
178
}
179