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 | 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\DataManager; |
||
12 | |||
13 | use CondorcetPHP\Condorcet\CondorcetVersion; |
||
14 | use CondorcetPHP\Condorcet\DataManager\DataHandlerDrivers\DataHandlerDriverInterface; |
||
15 | use CondorcetPHP\Condorcet\Throwable\CondorcetException; |
||
16 | |||
17 | abstract class ArrayManager implements \ArrayAccess, \Countable, \Iterator |
||
18 | { |
||
19 | use CondorcetVersion; |
||
20 | |||
21 | ////// |
||
22 | |||
23 | public static $CacheSize = 2000; |
||
24 | public static $MaxContainerLength = 2000; |
||
25 | |||
26 | protected $_Container = []; |
||
27 | protected $_DataHandler = null; |
||
28 | protected $_link = []; |
||
29 | |||
30 | protected $_Cache = []; |
||
31 | protected $_CacheMaxKey = 0; |
||
32 | protected $_CacheMinKey = 0; |
||
33 | |||
34 | protected $_cursor = null; |
||
35 | protected $_counter = 0; |
||
36 | protected $_maxKey = -1; |
||
37 | |||
38 | public function __construct () {} |
||
39 | |||
40 | public function __destruct () |
||
41 | { |
||
42 | $this->regularize(); |
||
43 | } |
||
44 | |||
45 | 1 | public function __clone () |
|
46 | { |
||
47 | 1 | $this->_link = []; |
|
48 | 1 | } |
|
49 | |||
50 | 2 | public function __sleep () : array |
|
51 | { |
||
52 | 2 | $this->regularize(); |
|
53 | 2 | $this->clearCache(); |
|
54 | 2 | $this->rewind(); |
|
55 | |||
56 | 2 | return ['_Container','_DataHandler','_link']; |
|
57 | } |
||
58 | |||
59 | 2 | public function __wakeup () |
|
60 | { |
||
61 | 2 | $this->resetMaxKey(); |
|
62 | 2 | $this->resetCounter(); |
|
63 | 2 | } |
|
64 | |||
65 | |||
66 | /////////// Implement ArrayAccess /////////// |
||
67 | |||
68 | 131 | public function offsetSet($offset, $value) : void |
|
69 | { |
||
70 | 131 | if ($offset === null) : |
|
71 | 131 | $this->_Container[++$this->_maxKey] = $value; |
|
72 | 131 | ++$this->_counter; |
|
73 | else : |
||
74 | 1 | $state = $this->keyExist($offset); |
|
75 | 1 | $this->_Container[$offset] = $value; |
|
76 | |||
77 | 1 | if (!$state) : |
|
78 | ++$this->_counter; |
||
79 | |||
80 | if ($offset > $this->_maxKey) : |
||
81 | $this->_maxKey = $offset; |
||
82 | endif; |
||
83 | |||
84 | ksort($this->_Container,SORT_NUMERIC); |
||
85 | 1 | elseif ($this->_DataHandler !== null) : |
|
86 | 1 | $this->_DataHandler->deleteOneEntity($offset, true); |
|
87 | endif; |
||
88 | |||
89 | 1 | $this->clearCache(); |
|
90 | endif; |
||
91 | |||
92 | 131 | $this->checkRegularize(); |
|
93 | 131 | } |
|
94 | |||
95 | // Use by isset() function, must return false if offset value is null. |
||
96 | public function offsetExists($offset) : bool |
||
97 | { |
||
98 | return ( isset($this->_Container[$offset]) || ($this->_DataHandler !== null && $this->_DataHandler->selectOneEntity($offset) !== false) ) ? true : false ; |
||
99 | } |
||
100 | |||
101 | 8 | public function offsetUnset($offset) : void |
|
102 | { |
||
103 | 8 | if ($this->keyExist($offset)) : |
|
104 | 8 | if (array_key_exists($offset, $this->_Container)) : |
|
105 | 8 | $this->preDeletedTask($this->_Container[$offset]); |
|
106 | 8 | unset($this->_Container[$offset]); |
|
107 | else : |
||
108 | 1 | if (array_key_exists($offset, $this->_Cache)) : |
|
109 | 1 | $this->preDeletedTask($this->_Cache[$offset]); |
|
110 | 1 | unset($this->_Cache[$offset]); |
|
111 | endif; |
||
112 | |||
113 | 1 | $this->_DataHandler->deleteOneEntity($offset, false); |
|
114 | endif; |
||
115 | |||
116 | 8 | --$this->_counter; |
|
117 | endif; |
||
118 | 8 | } |
|
119 | |||
120 | 104 | public function offsetGet($offset) |
|
121 | { |
||
122 | 104 | if (isset($this->_Container[$offset])) : |
|
123 | 102 | return $this->_Container[$offset]; |
|
124 | 4 | elseif ($this->_DataHandler !== null) : |
|
125 | 4 | if (array_key_exists($offset, $this->_Cache)) : |
|
126 | 4 | return $this->_Cache[$offset]; |
|
127 | else : |
||
128 | 4 | $oneEntity = $this->_DataHandler->selectOneEntity($offset); |
|
129 | 4 | if ($oneEntity === false) : |
|
130 | return null; |
||
131 | else : |
||
132 | 4 | $this->_Cache[$offset] = $oneEntity; |
|
133 | 4 | return $oneEntity; |
|
134 | endif; |
||
135 | endif; |
||
136 | else : |
||
137 | return null; |
||
138 | endif; |
||
139 | } |
||
140 | |||
141 | |||
142 | /////////// Implement Iterator /////////// |
||
143 | |||
144 | protected $valid = true; |
||
145 | |||
146 | 103 | public function rewind() : void { |
|
147 | 103 | $this->_cursor = null; |
|
148 | 103 | $this->valid = true; |
|
149 | |||
150 | 103 | reset($this->_Cache); |
|
151 | 103 | reset($this->_Container); |
|
152 | 103 | } |
|
153 | |||
154 | 103 | public function current() { |
|
155 | 103 | return $this->offsetGet($this->key()); |
|
156 | } |
||
157 | |||
158 | 103 | public function key() : ?int |
|
159 | { |
||
160 | 103 | if ($this->_counter === 0) : |
|
161 | return null; |
||
162 | else : |
||
163 | 103 | return $this->_cursor ?? $this->getFirstKey(); |
|
164 | endif; |
||
165 | } |
||
166 | |||
167 | 103 | public function next() : void |
|
168 | { |
||
169 | 103 | $oldCursor = $this->_cursor; |
|
170 | |||
171 | 103 | if ($this->_cursor >= $this->_maxKey) : |
|
172 | // Do nothing |
||
173 | 87 | elseif (!$this->isUsingHandler()) : |
|
174 | 84 | $this->setCursorOnNextKeyInArray($this->_Container); |
|
175 | else : |
||
176 | 4 | $this->populateCache(); |
|
177 | 4 | $this->setCursorOnNextKeyInArray($this->_Cache); |
|
178 | endif; |
||
179 | |||
180 | 103 | if ($this->_cursor === $oldCursor) : |
|
181 | 102 | $this->valid = false; |
|
182 | endif; |
||
183 | 103 | } |
|
184 | |||
185 | 87 | protected function setCursorOnNextKeyInArray (array &$array) : void |
|
186 | { |
||
187 | 87 | next($array); |
|
188 | 87 | $arrayKey = key($array); |
|
189 | |||
190 | 87 | if ($arrayKey > $this->key()) : |
|
191 | 87 | $this->_cursor = $arrayKey; |
|
192 | endif; |
||
193 | 87 | } |
|
194 | |||
195 | 103 | public function valid() : bool { |
|
196 | 103 | return ($this->_counter !== 0) ? $this->valid : false; |
|
197 | } |
||
198 | |||
199 | |||
200 | /////////// Implement Countable /////////// |
||
201 | |||
202 | 16 | public function count () : int { |
|
203 | 16 | return $this->_counter; |
|
204 | } |
||
205 | |||
206 | /////////// Array Methods /////////// |
||
207 | |||
208 | 14 | public function getFullDataSet () : array |
|
209 | { |
||
210 | 14 | if ($this->isUsingHandler()) : |
|
211 | 1 | $this->regularize(); |
|
212 | 1 | $this->clearCache(); |
|
213 | |||
214 | 1 | return $this->_Cache = $this->_DataHandler->selectRangeEntitys(0,$this->_maxKey + 1); |
|
215 | else : |
||
216 | 13 | return $this->_Container; |
|
217 | endif; |
||
218 | } |
||
219 | |||
220 | 9 | public function keyExist ($offset) : bool |
|
221 | { |
||
222 | 9 | if ( array_key_exists($offset, $this->_Container) || ($this->_DataHandler !== null && $this->_DataHandler->selectOneEntity($offset) !== false) ) : |
|
223 | 9 | return true; |
|
224 | else : |
||
225 | 1 | return false; |
|
226 | endif; |
||
227 | } |
||
228 | |||
229 | 103 | public function getFirstKey () : int |
|
230 | { |
||
231 | 103 | $r = array_keys($this->_Container); |
|
232 | |||
233 | 103 | if ($this->_DataHandler !== null) : |
|
234 | 4 | $r[] = $this->_DataHandler->selectMinKey(); |
|
235 | endif; |
||
236 | |||
237 | 103 | return (int) min($r); |
|
238 | } |
||
239 | |||
240 | 9 | public function getContainerSize () : int |
|
241 | { |
||
242 | 9 | return count($this->_Container); |
|
243 | } |
||
244 | |||
245 | 1 | public function getCacheSize () : int |
|
246 | { |
||
247 | 1 | return count($this->_Cache); |
|
248 | } |
||
249 | |||
250 | 1 | public function debugGetCache () : array |
|
251 | { |
||
252 | 1 | return $this->_Cache; |
|
253 | } |
||
254 | |||
255 | |||
256 | /////////// HANDLER API /////////// |
||
257 | |||
258 | abstract protected function preDeletedTask ($object) : void; |
||
259 | |||
260 | 9 | public function regularize () : bool |
|
261 | { |
||
262 | 9 | if (!$this->isUsingHandler() || empty($this->_Container)) : |
|
263 | 9 | return false; |
|
264 | else : |
||
265 | 6 | $this->_DataHandler->insertEntitys($this->_Container); |
|
266 | 6 | $this->_Container = []; |
|
267 | 6 | return true; |
|
268 | endif; |
||
269 | } |
||
270 | |||
271 | 131 | public function checkRegularize () : bool |
|
272 | { |
||
273 | 131 | if ( $this->_DataHandler !== null && self::$MaxContainerLength <= $this->getContainerSize() ) : |
|
274 | 4 | $this->regularize(); |
|
275 | 4 | return true; |
|
276 | else : |
||
277 | 131 | return false; |
|
278 | endif; |
||
279 | } |
||
280 | |||
281 | 4 | protected function populateCache () : void |
|
282 | { |
||
283 | 4 | $this->regularize(); |
|
284 | |||
285 | 4 | $currentKey = $this->key(); |
|
286 | |||
287 | 4 | if ( empty($this->_Cache) || $currentKey >= $this->_CacheMaxKey || $currentKey < $this->_CacheMinKey ) : |
|
288 | 4 | $this->clearCache(); |
|
289 | 4 | $this->_Cache = $this->_DataHandler->selectRangeEntitys($currentKey, self::$CacheSize); |
|
290 | |||
291 | 4 | $keys = array_keys($this->_Cache); |
|
292 | 4 | $this->_CacheMaxKey = max($keys); |
|
293 | 4 | $this->_CacheMinKey = min($keys); |
|
294 | endif; |
||
295 | 4 | } |
|
296 | |||
297 | 7 | public function clearCache () : void |
|
298 | { |
||
299 | 7 | foreach ($this->_Cache as $e) : |
|
300 | 5 | $this->preDeletedTask($e); |
|
301 | endforeach; |
||
302 | |||
303 | 7 | $this->_Cache = []; |
|
304 | 7 | $this->_CacheMaxKey = 0; |
|
305 | 7 | $this->_CacheMinKey = 0; |
|
306 | 7 | } |
|
307 | |||
308 | 100 | public function isUsingHandler () |
|
309 | { |
||
310 | 100 | return $this->_DataHandler !== null; |
|
311 | } |
||
312 | |||
313 | /////////// HANDLER INTERRACTION /////////// |
||
314 | |||
315 | 9 | public function resetCounter () : int |
|
316 | { |
||
317 | 9 | return $this->_counter = $this->getContainerSize() + ( $this->isUsingHandler() ? $this->_DataHandler->countEntitys() : 0 ); |
|
318 | } |
||
319 | |||
320 | 9 | public function resetMaxKey () : ?int |
|
321 | { |
||
322 | 9 | $this->resetCounter(); |
|
323 | |||
324 | 9 | if ($this->count() < 1) : |
|
325 | 7 | $this->_maxKey = -1; |
|
326 | 7 | return null; |
|
327 | else : |
||
328 | 3 | $maxContainerKey = empty($this->_Container) ? null : max(array_keys($this->_Container)); |
|
329 | 3 | $maxHandlerKey = $this->_DataHandler !== null ? $this->_DataHandler->selectMaxKey() : null; |
|
330 | |||
331 | 3 | return $this->_maxKey = max( $maxContainerKey,$maxHandlerKey ); |
|
332 | endif; |
||
333 | } |
||
334 | |||
335 | 7 | public function importHandler (DataHandlerDriverInterface $handler) : bool |
|
336 | { |
||
337 | 7 | if ($handler->countEntitys() === 0) : |
|
338 | 7 | $this->_DataHandler = $handler; |
|
339 | 7 | $this->_DataHandler->_dataContextObject = $this->getDataContextObject(); |
|
0 ignored issues
–
show
|
|||
340 | |||
341 | try { |
||
342 | 7 | $this->regularize(); |
|
343 | } catch (\Exception $e) { |
||
344 | $this->_DataHandler = null; |
||
345 | $this->resetCounter(); |
||
346 | $this->resetMaxKey(); |
||
347 | throw $e; |
||
348 | } |
||
349 | |||
350 | 7 | $this->resetCounter(); |
|
351 | 7 | $this->resetMaxKey(); |
|
352 | |||
353 | 7 | return true; |
|
354 | else : |
||
355 | throw new CondorcetException; |
||
356 | endif; |
||
357 | } |
||
358 | |||
359 | 1 | public function closeHandler () : void |
|
360 | { |
||
361 | 1 | if ($this->_DataHandler !== null) : |
|
362 | 1 | $this->regularize(); |
|
363 | 1 | $this->clearCache(); |
|
364 | |||
365 | 1 | $this->_Container = $this->_DataHandler->selectRangeEntitys(0,$this->_maxKey + 1); |
|
366 | |||
367 | 1 | $this->_DataHandler = null; |
|
368 | |||
369 | 1 | $this->resetCounter(); |
|
370 | 1 | $this->resetMaxKey(); |
|
371 | endif; |
||
372 | 1 | } |
|
373 | |||
374 | abstract public function getDataContextObject () : DataContextInterface; |
||
375 | } |
||
376 |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: