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 | /** |
||
4 | * m'Manager | Invoices Management System |
||
5 | * |
||
6 | * This content is released under the Proprietary License (Proprietary) |
||
7 | * |
||
8 | * Copyright (c) 2017, Eric Claver AKAFFOU - All Rights Reserved |
||
9 | * Unauthorized copying of this file, via any medium is strictly prohibited |
||
10 | * Proprietary and confidential |
||
11 | * |
||
12 | * @package m'Manager |
||
13 | * @author Eric Claver AKAFFOU |
||
14 | * @copyright Copyright (c) 2017, on'Eric Computing, Inc. (https://www.onericcomputing.com/) |
||
15 | * @license https://www.mmanager.fr Proprietary License |
||
16 | * @link https://codecanyon.net/item/mmanager-invoices-management-system/19866435?s_rank=1 |
||
17 | * @since Version 1.0.0 |
||
18 | * @filesource |
||
19 | */ |
||
20 | |||
21 | namespace Mmanager\Utils; |
||
22 | |||
23 | use Mmanager\Contract\ParserInterface; |
||
24 | |||
25 | class CsvParser implements ParserInterface { |
||
26 | |||
27 | private $handle = ""; |
||
28 | private $filepath = FALSE; |
||
29 | private $column_headers = FALSE; |
||
30 | private $initial_line = 0; |
||
31 | private $delimiter = ","; |
||
32 | private $detect_line_endings = FALSE; |
||
33 | |||
34 | /** |
||
35 | * Function that parses a CSV file and returns results |
||
36 | * as an array. |
||
37 | * |
||
38 | * @access public |
||
39 | * @param filepath string Location of the CSV file |
||
40 | * @param column_headers array Alternate values that will be used for array keys instead of first line of CSV |
||
41 | * @param detect_line_endings boolean When true sets the php INI settings to allow script to detect line endings. Needed for CSV files created on Macs. |
||
42 | * @param initial_line integer Sets the line of the file from which start parsing data. |
||
43 | * @param delimiter string The values delimiter (e.g. ";" or ","). |
||
44 | * @return array |
||
45 | */ |
||
46 | public function parse($filepath=FALSE, $column_headers=FALSE, $detect_line_endings=FALSE, $initial_line=FALSE, $delimiter=FALSE) |
||
47 | { |
||
48 | // Raise memory limit (for big files) |
||
49 | ini_set('memory_limit', '128M'); |
||
50 | |||
51 | // File path |
||
52 | if(! $filepath) |
||
0 ignored issues
–
show
|
|||
53 | { |
||
54 | $filepath = $this->_get_filepath(); |
||
55 | } |
||
56 | else |
||
57 | { |
||
58 | // If filepath provided, set it |
||
59 | $this->_set_filepath($filepath); |
||
60 | } |
||
61 | |||
62 | // If file doesn't exists, return false |
||
63 | if(! file_exists($filepath)) |
||
64 | { |
||
65 | return FALSE; |
||
0 ignored issues
–
show
The return type of
return FALSE; (false ) is incompatible with the return type documented by Mmanager\Utils\CsvParser::parse of type array .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
66 | } |
||
67 | |||
68 | // auto detect row endings |
||
69 | if(! $detect_line_endings) |
||
70 | { |
||
71 | $detect_line_endings = $this->_get_detect_line_endings(); |
||
72 | } |
||
73 | else |
||
74 | { |
||
75 | // If detect_line_endings provided, set it |
||
76 | $this->_set_detect_line_endings($detect_line_endings); |
||
77 | } |
||
78 | |||
79 | // If true, auto detect row endings |
||
80 | if($detect_line_endings) |
||
81 | { |
||
82 | ini_set("auto_detect_line_endings", TRUE); |
||
83 | } |
||
84 | |||
85 | // Parse from this line on |
||
86 | if(! $initial_line) |
||
0 ignored issues
–
show
The expression
$initial_line of type false|integer is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
87 | { |
||
88 | $initial_line = $this->_get_initial_line(); |
||
0 ignored issues
–
show
$initial_line is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
89 | } |
||
90 | else |
||
91 | { |
||
92 | $this->_set_initial_line($initial_line); |
||
93 | } |
||
94 | |||
95 | // Delimiter |
||
96 | if(! $delimiter) |
||
0 ignored issues
–
show
The expression
$delimiter of type false|string is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
97 | { |
||
98 | $delimiter = $this->_get_delimiter(); |
||
0 ignored issues
–
show
$delimiter is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
99 | } |
||
100 | else |
||
101 | { |
||
102 | // If delimiter provided, set it |
||
103 | $this->_set_delimiter($delimiter); |
||
104 | } |
||
105 | |||
106 | // Column headers |
||
107 | if(! $column_headers) |
||
108 | { |
||
109 | $column_headers = $this->_get_column_headers(); |
||
110 | } |
||
111 | else |
||
112 | { |
||
113 | // If column headers provided, set them |
||
114 | $this->_set_column_headers($column_headers); |
||
115 | } |
||
116 | |||
117 | // Open the CSV for reading |
||
118 | $this->_get_handle(); |
||
119 | |||
120 | $row = 0; |
||
121 | |||
122 | while (($data = fgetcsv($this->handle, 0, $this->delimiter)) !== FALSE) |
||
123 | { |
||
124 | if ($data[0] != NULL) |
||
125 | { |
||
126 | if($row < $this->initial_line) |
||
127 | { |
||
128 | $row++; |
||
129 | continue; |
||
130 | } |
||
131 | |||
132 | // If first row, parse for column_headers |
||
133 | if($row == $this->initial_line) |
||
134 | { |
||
135 | // If column_headers already provided, use them |
||
136 | if($this->column_headers) |
||
137 | { |
||
138 | foreach ($this->column_headers as $key => $value) |
||
0 ignored issues
–
show
|
|||
139 | { |
||
140 | $column_headers[$key] = trim($value); |
||
141 | } |
||
142 | } |
||
143 | else // Parse first row for column_headers to use |
||
144 | { |
||
145 | foreach ($data as $key => $value) |
||
146 | { |
||
147 | $column_headers[$key] = trim($value); |
||
148 | } |
||
149 | } |
||
150 | } |
||
151 | else |
||
152 | { |
||
153 | $new_row = $row - $this->initial_line - 1; // needed so that the returned array starts at 0 instead of 1 |
||
154 | foreach($column_headers as $key => $value) // assumes there are as many columns as their are title columns |
||
0 ignored issues
–
show
The expression
$column_headers of type boolean|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
155 | { |
||
156 | $result[$new_row][$value] = utf8_encode(trim($data[$key])); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
157 | } |
||
158 | } |
||
159 | |||
160 | unset($data); |
||
161 | |||
162 | $row++; |
||
163 | } |
||
164 | } |
||
165 | |||
166 | $this->_close_csv(); |
||
167 | |||
168 | return $result; |
||
0 ignored issues
–
show
The variable
$result does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
169 | } |
||
170 | |||
171 | |||
172 | |||
173 | /** |
||
174 | * Sets the "detect_line_endings" flag |
||
175 | * |
||
176 | * @access private |
||
177 | * @param detect_line_endings bool The flag bit |
||
178 | * @return void |
||
179 | */ |
||
180 | private function _set_detect_line_endings($detect_line_endings) |
||
181 | { |
||
182 | $this->detect_line_endings = $detect_line_endings; |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Sets the "detect_line_endings" flag |
||
187 | * |
||
188 | * @access public |
||
189 | * @param detect_line_endings bool The flag bit |
||
190 | * @return void |
||
191 | */ |
||
192 | public function detect_line_endings($detect_line_endings) |
||
193 | { |
||
194 | $this->_set_detect_line_endings($detect_line_endings); |
||
195 | return $this; |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Gets the "detect_line_endings" flag |
||
200 | * |
||
201 | * @access private |
||
202 | * @return bool |
||
203 | */ |
||
204 | private function _get_detect_line_endings() |
||
205 | { |
||
206 | return $this->detect_line_endings; |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * Sets the initial line from which start to parse the file |
||
211 | * |
||
212 | * @access private |
||
213 | * @param initial_line int Start parse from this line |
||
214 | * @return void |
||
215 | */ |
||
216 | private function _set_initial_line($initial_line) |
||
217 | { |
||
218 | return $this->initial_line = $initial_line; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * Sets the initial line from which start to parse the file |
||
223 | * |
||
224 | * @access public |
||
225 | * @param initial_line int Start parse from this line |
||
226 | * @return void |
||
227 | */ |
||
228 | public function initial_line($initial_line) |
||
229 | { |
||
230 | $this->_set_initial_line($initial_line); |
||
231 | return $this; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Gets the initial line from which start to parse the file |
||
236 | * |
||
237 | * @access private |
||
238 | * @return int |
||
239 | */ |
||
240 | private function _get_initial_line() |
||
241 | { |
||
242 | return $this->initial_line; |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * Sets the values delimiter |
||
247 | * |
||
248 | * @access private |
||
249 | * @param initial_line string The values delimiter (eg. "," or ";") |
||
250 | * @return void |
||
251 | */ |
||
252 | private function _set_delimiter($delimiter) |
||
253 | { |
||
254 | $this->delimiter = $delimiter; |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Sets the values delimiter |
||
259 | * |
||
260 | * @access public |
||
261 | * @param initial_line string The values delimiter (eg. "," or ";") |
||
262 | * @return void |
||
263 | */ |
||
264 | public function delimiter($delimiter) |
||
265 | { |
||
266 | $this->_set_delimiter($delimiter); |
||
267 | return $this; |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * Gets the values delimiter |
||
272 | * |
||
273 | * @access private |
||
274 | * @return string |
||
275 | */ |
||
276 | private function _get_delimiter() |
||
277 | { |
||
278 | return $this->delimiter; |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Sets the filepath of a given CSV file |
||
283 | * |
||
284 | * @access private |
||
285 | * @param filepath string Location of the CSV file |
||
286 | * @return void |
||
287 | */ |
||
288 | private function _set_filepath($filepath) |
||
289 | { |
||
290 | $this->filepath = $filepath; |
||
0 ignored issues
–
show
The property
$filepath was declared of type boolean , but $filepath is of type string . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
291 | } |
||
292 | |||
293 | /** |
||
294 | * Sets the filepath of a given CSV file |
||
295 | * |
||
296 | * @access public |
||
297 | * @param filepath string Location of the CSV file |
||
298 | * @return void |
||
299 | */ |
||
300 | public function filepath($filepath) |
||
301 | { |
||
302 | $this->_set_filepath($filepath); |
||
303 | return $this; |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * Gets the filepath of a given CSV file |
||
308 | * |
||
309 | * @access private |
||
310 | * @return string |
||
311 | */ |
||
312 | private function _get_filepath() |
||
313 | { |
||
314 | return $this->filepath; |
||
315 | } |
||
316 | |||
317 | /** |
||
318 | * Sets the alternate column headers that will be used when creating the array |
||
319 | * |
||
320 | * @access private |
||
321 | * @param column_headers array Alternate column_headers that will be used instead of first line of CSV |
||
322 | * @return void |
||
323 | */ |
||
324 | private function _set_column_headers($column_headers='') |
||
325 | { |
||
326 | if(is_array($column_headers) && !empty($column_headers)) |
||
327 | { |
||
328 | $this->column_headers = $column_headers; |
||
0 ignored issues
–
show
It seems like
$column_headers of type array is incompatible with the declared type boolean of property $column_headers .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
329 | } |
||
330 | } |
||
331 | |||
332 | /** |
||
333 | * Sets the alternate column headers that will be used when creating the array |
||
334 | * |
||
335 | * @access public |
||
336 | * @param column_headers array Alternate column_headers that will be used instead of first line of CSV |
||
337 | * @return void |
||
338 | */ |
||
339 | public function column_headers($column_headers) |
||
340 | { |
||
341 | $this->_set_column_headers($column_headers); |
||
342 | return $this; |
||
343 | } |
||
344 | |||
345 | /** |
||
346 | * Gets the alternate column headers that will be used when creating the array |
||
347 | * |
||
348 | * @access private |
||
349 | * @return mixed |
||
350 | */ |
||
351 | private function _get_column_headers() |
||
352 | { |
||
353 | return $this->column_headers; |
||
354 | } |
||
355 | |||
356 | /** |
||
357 | * Opens the CSV file for parsing |
||
358 | * |
||
359 | * @access private |
||
360 | * @return void |
||
361 | */ |
||
362 | private function _get_handle() |
||
363 | { |
||
364 | $this->handle = fopen($this->filepath, "r"); |
||
0 ignored issues
–
show
It seems like
fopen($this->filepath, 'r') of type resource is incompatible with the declared type string of property $handle .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Closes the CSV file when complete |
||
369 | * |
||
370 | * @access private |
||
371 | * @return array |
||
372 | */ |
||
373 | private function _close_csv() |
||
374 | { |
||
375 | fclose($this->handle); |
||
376 | } |
||
377 | } |
||
378 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: