Completed
Push — master ( 922505...49fe4c )
by Boudry
05:20
created

Condorcet::setDefaultMethod()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 7
nc 2
nop 1
crap 3
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 32 and the first side effect is on line 16.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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;
11
12
use Condorcet\CondorcetException;
13
use Condorcet\Result;
14
15
// Registering native Condorcet Methods implementation
16 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\Copeland');
17 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\DodgsonQuick');
18 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\DodgsonTidemanApproximation');
19 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\KemenyYoung');
20 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\MinimaxWinning');
21 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\MinimaxMargin');
22 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\MinimaxOpposition');
23 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\RankedPairsMargin');
24 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\RankedPairsWinning');
25 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\SchulzeWinning');
26 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\SchulzeMargin');
27 8
Condorcet::addMethod(__NAMESPACE__.'\\Algo\\Methods\\SchulzeRatio');
28
29
// Set the default Condorcet Class algorithm
30 8
Condorcet::setDefaultMethod('Schulze');
31
32
abstract class Condorcet
33
{
34
35
/////////// CONSTANTS ///////////
36
    public const VERSION = '1.5.0';
37
38
    public const CONDORCET_BASIC_CLASS = __NAMESPACE__.'\\Algo\\Methods\\CondorcetBasic';
39
40
    protected static $_defaultMethod = null;
41
    protected static $_authMethods = [ self::CONDORCET_BASIC_CLASS => (__NAMESPACE__.'\\Algo\\Methods\\CondorcetBasic')::METHOD_NAME ];
42
43
44
/////////// STATICS METHODS ///////////
45
46
    // Return library version numer
47 4
    public static function getVersion (string $options = 'FULL') : string
48
    {
49 4
        switch ($options) :
50
            case 'MAJOR':
51 2
                $version = explode('.', self::VERSION);
52 2
                return $version[0].'.'.$version[1];
53
54
            default:
55 4
                return self::VERSION;
56
        endswitch;
57
    }
58
59
    // Return an array with auth methods
60 1
    public static function getAuthMethods (bool $basic = false) : array
61
    {
62 1
        $auth = self::$_authMethods;
63
64
        // Don't show Natural Condorcet
65 1
        if (!$basic) :
66 1
            unset($auth[self::CONDORCET_BASIC_CLASS]);
67
        endif;
68
69 1
        return array_column($auth,0);
70
    }
71
72
73
    // Return the Class default method
74 9
    public static function getDefaultMethod () {
75 9
        return self::$_defaultMethod;
76
    }
77
78
79
    // Check if the method is supported
80 68
    public static function isAuthMethod (string $method)
81
    {
82 68
        $auth = self::$_authMethods;
83
84 68
        if (empty($method)) :
85 1
            throw new CondorcetException (8);
86
        endif;
87
88 67
        if ( isset($auth[$method]) ) :
89 10
            return $method;
90
        else : // Alias
91 65
            foreach ($auth as $class => &$alias) :
92 65
                foreach ($alias as &$entry) :
93 65
                    if ( strcasecmp($method,$entry) === 0 ) :
94 65
                        return $class;
95
                    endif;
96
                endforeach;
97
            endforeach;
98
        endif;
99
100 10
        return false;
101
    }
102
103
104
    // Add algos
105 9
    public static function addMethod (string $algos) : bool
106
    {
107
        // Check algos
108 9
        if ( self::isAuthMethod($algos) || !self::testMethod($algos) ) :
109 1
            return false;
110
        endif;
111
112
        // Adding algo
113 8
        self::$_authMethods[$algos] = $algos::METHOD_NAME;
114
115 8
        if (self::getDefaultMethod() === null) :
116 8
            self::setDefaultMethod($algos);
117
        endif;
118
119 8
        return true;
120
    }
121
122
123
        // Check if the class Algo. exist and ready to be used
124 8
        protected static function testMethod (string $method) : bool
125
        {
126 8
            if ( !class_exists($method) ) :             
127
                throw new CondorcetException(9);
128
            endif;
129
130 8
            if ( !is_subclass_of($method, __NAMESPACE__.'\\Algo\\MethodInterface') || !is_subclass_of($method,__NAMESPACE__.'\\Algo\\Method') ) :
2 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if __NAMESPACE__ . '\\Algo\\MethodInterface' can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if __NAMESPACE__ . '\\Algo\\Method' can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
131 1
                throw new CondorcetException(10);
132
            endif;
133
134 8
            foreach ($method::METHOD_NAME as $alias) :
135 8
                if (self::isAuthMethod($alias)) :
136 8
                    throw new CondorcetException(25);
137
                endif;
138
            endforeach;
139
140 8
            return true;
141
        }
142
143
144
    // Change default method for this class.
145 9
    public static function setDefaultMethod (string $method) : bool
146
    {       
147 9
        if ( ($method = self::isAuthMethod($method)) && $method !== self::CONDORCET_BASIC_CLASS ) :
148 8
            self::$_defaultMethod = $method;
149 8
            return true;
150
        else :
151 1
            return false;
152
        endif;
153
    }
154
155
    // Simplify Condorcet Var_Dump. Transform object to String.
156 50
    public static function format ($input, bool $convertObject = true)
157
    {
158 50
        if (is_object($input)) :
159
            
160 50
            $r = $input;
161
162 50
            if ($convertObject) :
163 3
                if ($input instanceof Candidate) :
164 1
                    $r = (string) $input;
165 3
                elseif ($input instanceof Vote) :
166
                    $r = $input->getRanking();
167 3
                elseif ($input instanceof Result) :
168 50
                    $r = $input->getResultAsArray(true);
169
                endif;
170
            endif;
171
172 49
        elseif (!is_array($input)) :
173 2
            $r = $input;
174
        else :
175 49
            foreach ($input as $key => $line) :
176 49
                $input[$key] = self::format($line,$convertObject);
177
            endforeach;
178
179 49
            if (count($input) === 1 && is_int(key($input)) && (!is_array(reset($input)) || count(reset($input)) === 1)):
180 42
                $r = reset($input);
181
            else:
182 7
                $r = $input;
183
            endif;
184
        endif;
185
        
186 50
        return $r;
187
    }
188
}