This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace PierceMcGeough\phpquartiles; |
||
4 | |||
5 | class Quartile |
||
6 | { |
||
7 | private $scores; |
||
8 | |||
9 | private $quartiles; |
||
10 | |||
11 | /** |
||
12 | * Create a new Quartiles Instance |
||
13 | * @param array $scores |
||
14 | */ |
||
15 | public function __construct(array $scores) |
||
16 | { |
||
17 | $this->scores = $scores; |
||
18 | |||
19 | if (!$this->arrayOnlyContainsNumbers()) { |
||
20 | throw new \Exception('Scores can only contain numbers'); |
||
21 | } |
||
22 | |||
23 | $this->calculateQuartiles(); |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * Calculate the quartiles |
||
28 | */ |
||
29 | private function calculateQuartiles() |
||
30 | { |
||
31 | if (count($this->scores)+1 <= 3) { |
||
32 | return; |
||
33 | } |
||
34 | |||
35 | sort($this->scores, SORT_NUMERIC); |
||
36 | |||
37 | $this->quartiles = [ |
||
38 | 'q1' => $this->getQuartile(0.25), |
||
39 | 'q2' => $this->getQuartile(0.50), |
||
40 | 'q3' => $this->getQuartile(0.75) |
||
41 | ]; |
||
42 | } |
||
43 | |||
44 | /** |
||
45 | * Get the quartiles |
||
46 | * |
||
47 | * @return array|void |
||
48 | */ |
||
49 | public function getAllQuartiles() |
||
50 | { |
||
51 | return $this->quartiles; |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * @return numeric |
||
56 | */ |
||
57 | public function getFirstQuartile() |
||
58 | { |
||
59 | return $this->quartiles['q1']; |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * @return numeric |
||
64 | */ |
||
65 | public function getMedianQuartile() |
||
66 | { |
||
67 | return $this->quartiles['q2']; |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * @return numeric |
||
72 | */ |
||
73 | public function getSecondQuartile() |
||
74 | { |
||
75 | return $this->getMedianQuartile(); |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * @return numeric |
||
80 | */ |
||
81 | public function getThirdQuartile() |
||
82 | { |
||
83 | return $this->quartiles['q3']; |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Use the params to work out the quartile specific to this $array |
||
88 | * |
||
89 | * @param double $quartilePlace |
||
90 | * @return float |
||
91 | */ |
||
92 | public function getQuartile($quartilePlace) |
||
93 | { |
||
94 | $pos = (count($this->scores) + 1) * $quartilePlace; |
||
95 | |||
96 | if (fmod($pos, 1) == 0) { |
||
97 | return $this->scores[$pos-1]; |
||
98 | } |
||
99 | |||
100 | $fraction = $pos - floor($pos); |
||
101 | |||
102 | $lower_num = $this->scores[floor($pos) - 1]; |
||
103 | $upper_num = $this->scores[ceil($pos) - 1]; |
||
104 | |||
105 | $difference = $upper_num - $lower_num; |
||
106 | |||
107 | return round($lower_num + ($difference * $fraction), 2); |
||
108 | } |
||
109 | |||
110 | public function getPlacement($value) |
||
111 | { |
||
112 | $belongsIn = [ |
||
113 | 'LOWEST_QUARTILE' => $value <= $this->quartiles['q1'], |
||
114 | 'SECOND_QUARTILE' => $this->belongsIn('q1', 'q2', $value), |
||
115 | 'THIRD_QUARTILE' => $this->belongsIn('q2', 'q3', $value), |
||
116 | 'HIGHEST_QUARTILE' => $value > $this->quartiles['q3'], |
||
117 | ]; |
||
118 | |||
119 | if ($belongsIn['SECOND_QUARTILE'] && $belongsIn['THIRD_QUARTILE'] && $value >= $this->quartiles['q3']) { |
||
120 | $belongsIn['HIGHEST_QUARTILE'] = true; |
||
121 | } |
||
122 | |||
123 | return $this->extractBelongsIn($belongsIn); |
||
124 | } |
||
125 | |||
126 | public function getPlacementInverse($value) |
||
127 | { |
||
128 | $belongsIn = [ |
||
129 | 'LOWEST_QUARTILE' => $value > $this->quartiles['q3'], |
||
130 | 'THIRD_QUARTILE' => $this->belongsIn('q1', 'q3', $value), |
||
131 | 'SECOND_QUARTILE' => $this->belongsIn('q2', 'q3', $value), |
||
132 | 'HIGHEST_QUARTILE' => $value <= $this->quartiles['q1'], |
||
133 | ]; |
||
134 | |||
135 | return $this->extractBelongsIn($belongsIn); |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Check if $value belongs in a quartile |
||
140 | * |
||
141 | * @param string $q1 |
||
142 | * @param string $q2 |
||
143 | * @param float $value |
||
144 | * |
||
145 | * @return boolean |
||
146 | */ |
||
147 | public function belongsIn($q1, $q2, $value) |
||
148 | { |
||
149 | if ($this->quartiles[$q1] == $this->quartiles[$q2]) { // Spans multiples |
||
150 | return ($value >= $this->quartiles[$q1] && $value <= $this->quartiles[$q2]); |
||
151 | } else { |
||
152 | return ($value > $this->quartiles[$q1] && $value <= $this->quartiles[$q2]); |
||
153 | } |
||
154 | |||
155 | return false; |
||
0 ignored issues
–
show
|
|||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Find the first TRUE value |
||
160 | * |
||
161 | * @param array $belongsIn |
||
162 | * |
||
163 | * @return string |
||
164 | */ |
||
165 | public function extractBelongsIn($belongsIn) |
||
166 | { |
||
167 | // Find the first TRUE value from bottom to top (hence array_reverse) |
||
168 | foreach (array_reverse($belongsIn) as $placement => $active) { |
||
169 | if ($active) { |
||
170 | return $placement; |
||
171 | } |
||
172 | } |
||
173 | |||
174 | return 'NONE'; |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Validate that the scores array only contains numbers |
||
179 | * |
||
180 | * @return boolean |
||
181 | */ |
||
182 | private function arrayOnlyContainsNumbers() |
||
183 | { |
||
184 | foreach ($this->scores as $score) { |
||
185 | if (!is_numeric($score)) { |
||
186 | return false; |
||
187 | } |
||
188 | } |
||
189 | |||
190 | return true; |
||
191 | } |
||
192 | } |
||
193 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.