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 | namespace Guer\HTMLTable; |
||
3 | |||
4 | /** |
||
5 | * Class that generates a table in HTML with table data from an array of objects. |
||
6 | * |
||
7 | * Through a table specification array it is possible to set an CSS id or |
||
8 | * a class for the table and a caption. |
||
9 | * |
||
10 | * Through a column specification it is possible to set the column title, set |
||
11 | * a colspan for the table cell and footer cell, through type determine if the |
||
12 | * row of cells belongs to the table body or table foot and through a function |
||
13 | * include advanced settings for a column. |
||
14 | * |
||
15 | * @author Gunnar Eriksson <[email protected]> |
||
16 | */ |
||
17 | class CHTMLTable |
||
18 | { |
||
19 | const FOOTER = 'footer'; |
||
20 | |||
21 | private $tableSpec; |
||
22 | private $tableHead; |
||
23 | private $tableBody; |
||
24 | private $tableFoot; |
||
25 | |||
26 | /** |
||
27 | * Constructor |
||
28 | * |
||
29 | * Creates a table with table head, table body and if specified, a table |
||
30 | * footer. It is possible to specify the table and the tabel cells settings |
||
31 | * per column. |
||
32 | * |
||
33 | * @param string[] $tableSpecs table settings. |
||
34 | * @param mixed[] $data table cell data. |
||
35 | * @param mixed[] $columnSpecs table columns cell settings. |
||
36 | */ |
||
37 | 11 | public function __construct($tableSpecs = [], $data = [], $columnSpecs = []) |
|
38 | { |
||
39 | 11 | $this->create($tableSpecs, $data, $columnSpecs); |
|
40 | 11 | } |
|
41 | |||
42 | /** |
||
43 | * Creates a table with cell data. |
||
44 | * |
||
45 | * Creates a table with table head, table body with table data and if |
||
46 | * specified, a table footer. It is possible to specify the table and the |
||
47 | * tabel cells settings per column. |
||
48 | * |
||
49 | * @param string[] $tableSpecs table settings. |
||
50 | * @param mixed[] $data table cell data. |
||
51 | * @param mixed[] $columnSpecs table columns cell settings. |
||
52 | * |
||
53 | * @return object the html table object. |
||
54 | */ |
||
55 | 11 | public function create($tableSpecs = [], $data = [], $columnSpecs = []) |
|
56 | { |
||
57 | 11 | $this->resetTableTags(); |
|
58 | 11 | $this->setTableSpecifications($tableSpecs); |
|
59 | |||
60 | 11 | $this->createTableHead($data, $columnSpecs); |
|
61 | 11 | $this->createTableBody($data, $columnSpecs); |
|
62 | 11 | $this->createTableFooter($columnSpecs); |
|
63 | |||
64 | 11 | return $this; |
|
65 | } |
||
66 | |||
67 | /** |
||
68 | * Helper method to reset main parts of table tags. |
||
69 | * |
||
70 | * Sets the table head, table body and table foot tag to null. |
||
71 | * |
||
72 | * @return void |
||
73 | */ |
||
74 | 11 | private function resetTableTags() |
|
75 | { |
||
76 | 11 | $this->tableHead = null; |
|
77 | 11 | $this->tableBody = null; |
|
78 | 11 | $this->tableFoot = null; |
|
79 | 11 | } |
|
80 | |||
81 | /** |
||
82 | * Helper method to set the table specifications. |
||
83 | * |
||
84 | * Merges the table specifications with the default specifications. |
||
85 | * Default table CSS id is html-table. |
||
86 | * |
||
87 | * @param string[] $tableSpec the table specification. |
||
88 | * |
||
89 | * @return void |
||
90 | */ |
||
91 | 11 | private function setTableSpecifications($tableSpec) |
|
92 | { |
||
93 | $defaults = [ |
||
94 | // Always have a id for the form |
||
95 | 11 | 'id' => 'html-table', |
|
96 | 11 | ]; |
|
97 | |||
98 | 11 | if ($this->isClassPresent($tableSpec)) { |
|
99 | 1 | $tableSpec = $this->removeId($tableSpec); |
|
100 | 1 | } |
|
101 | |||
102 | 11 | $this->tableSpec = array_merge($defaults, $tableSpec); |
|
103 | 11 | } |
|
104 | |||
105 | /** |
||
106 | * Helper method to check if a CSS class tag is present |
||
107 | * |
||
108 | * Checks if a CSS class tag is present in the table specification. |
||
109 | * |
||
110 | * @param string[] $tableSpec the table specification. |
||
111 | * |
||
112 | * @return boolean true if class is present in the table specification, |
||
113 | * false otherwise. |
||
114 | */ |
||
115 | 11 | private function isClassPresent($tableSpec) |
|
116 | { |
||
117 | 11 | return isset($tableSpec['class']) ? true : false; |
|
118 | } |
||
119 | |||
120 | /** |
||
121 | * Helper method to reset the id tag. |
||
122 | * |
||
123 | * Sets the CSS id tag to null. |
||
124 | * |
||
125 | * @param string[] $tableSpec the table specification. |
||
126 | * |
||
127 | * @return string[] the table specification without the CSS id tag. |
||
128 | */ |
||
129 | 1 | private function removeId($tableSpec) { |
|
130 | 1 | $tableSpec['id'] = null; |
|
131 | |||
132 | 1 | return $tableSpec; |
|
133 | } |
||
134 | |||
135 | /** |
||
136 | * Helper method to create the table head. |
||
137 | * |
||
138 | * Creates the table head. The title of the columns are set according to |
||
139 | * the table tag in the column specifications. Otherwise, the title is set |
||
140 | * to the keys name in the table cell data array. |
||
141 | * |
||
142 | * @param mixed[] $data table cell data. |
||
143 | * @param mixed[] $columnSpecs table columns cell settings. |
||
144 | * |
||
145 | * @return void |
||
146 | */ |
||
147 | 11 | private function createTableHead($data, $columnSpecs) |
|
148 | { |
||
149 | 11 | $this->tableHead = "\n<thead>"; |
|
150 | 11 | $this->tableHead .= "\n<tr>"; |
|
151 | |||
152 | 11 | if (empty($columnSpecs)) |
|
153 | 11 | { |
|
154 | 11 | $this->setColumnTitlesFromData($data); |
|
155 | 11 | } else { |
|
156 | 7 | $this->setColumnTitlesFromColumnSpecifications($columnSpecs); |
|
157 | } |
||
158 | |||
159 | 11 | $this->tableHead .= "\n</tr>"; |
|
160 | 11 | $this->tableHead .= "\n</thead>"; |
|
161 | 11 | } |
|
162 | |||
163 | /** |
||
164 | * Helper method to set the column titles from the data array. |
||
165 | * |
||
166 | * Uses the first row in the table cell data array to set the titles of |
||
167 | * the columns. The name of the columns are the key name for the objects in |
||
168 | * the array containing data for the table. |
||
169 | * |
||
170 | * @param mixed[] $data table cell data. |
||
171 | * |
||
172 | * @return void |
||
173 | */ |
||
174 | 11 | private function setColumnTitlesFromData($data) |
|
175 | { |
||
176 | 11 | $firstRow = isset($data[0]) ? $data[0] : []; |
|
177 | 11 | foreach ($firstRow as $key => $value) { |
|
178 | 4 | $this->tableHead .= "\n<th>"; |
|
179 | 4 | $this->tableHead .= htmlentities($key, null, 'UTF-8'); |
|
180 | 4 | $this->tableHead .= "</th>"; |
|
181 | 11 | } |
|
182 | 11 | } |
|
183 | |||
184 | /** |
||
185 | * Helper method to set the column titles from column specifications. |
||
186 | * |
||
187 | * Uses column specifications to set the name of the columns in the table |
||
188 | * head. |
||
189 | * |
||
190 | * @param mixed[] $columnSpecs table columns cell settings |
||
191 | * |
||
192 | * @return void |
||
193 | */ |
||
194 | 7 | private function setColumnTitlesFromColumnSpecifications($columnSpecs) |
|
195 | { |
||
196 | 7 | foreach ($columnSpecs as $key => $columnSpec) { |
|
197 | 7 | if (!$this->isTableFooter($columnSpec)) { |
|
198 | 7 | $this->tableHead .= "\n<th>"; |
|
199 | 7 | $this->tableHead .= $this->getTitle($key, $columnSpec); |
|
200 | 7 | $this->tableHead .= "</th>"; |
|
201 | 7 | } |
|
202 | 7 | } |
|
203 | 7 | } |
|
204 | |||
205 | /** |
||
206 | * Helper method to check if the column cell belongs to the footer. |
||
207 | * |
||
208 | * Checks the type tag, in the column specification for one column, if the |
||
209 | * tag is present and set to footer. |
||
210 | * |
||
211 | * @param mixed[] $columnSpec cell settings for one column. |
||
212 | * |
||
213 | * @return boolean true if the cell type belongs to the footer, false otherwise. |
||
214 | */ |
||
215 | 7 | private function isTableFooter($columnSpec) |
|
216 | { |
||
217 | 7 | $isFooter = false; |
|
218 | 7 | if (isset($columnSpec['type'])) { |
|
219 | 2 | if (strcmp($columnSpec['type'], self::FOOTER) === 0) { |
|
220 | 2 | $isFooter = true; |
|
221 | 2 | } |
|
222 | 2 | } |
|
223 | |||
224 | 7 | return $isFooter; |
|
225 | } |
||
226 | |||
227 | /** |
||
228 | * Helper method to get title from a column specification, if specified. |
||
229 | * |
||
230 | * Uses the title tag in the column specification for one column to get |
||
231 | * the title. If the title tag is not set, the title is the key for the |
||
232 | * objects int the array containing data for the table. |
||
233 | * |
||
234 | * @param string $key the name of the key for the table cell data. |
||
235 | * @param mixed[] $columnSpec cell settings for one column. |
||
236 | * |
||
237 | * @return string[] the name from the title tag in the cell specification. |
||
238 | * Otherwise, the table cell data key name. |
||
239 | */ |
||
240 | 7 | private function getTitle($key, $columnSpec) |
|
241 | { |
||
242 | 7 | return isset($columnSpec['title']) ? $columnSpec['title'] : $key; |
|
243 | } |
||
244 | |||
245 | /** |
||
246 | * Helper method to create the table body with table cell data. |
||
247 | * |
||
248 | * Sets the table cell data in the table body. |
||
249 | * |
||
250 | * @param mixed[] $data table cell data. |
||
251 | * @param mixed[] $columnSpecs table columns cell settings. |
||
252 | * |
||
253 | * @return void |
||
254 | */ |
||
255 | 11 | private function createTableBody($data, $columnSpecs) |
|
256 | { |
||
257 | 11 | $this->setTableData($data, $columnSpecs); |
|
258 | 11 | if (isset($this->tableBody)) { |
|
259 | 11 | $this->tableBody = "\n<tbody>" . $this->tableBody . "\n</tbody>"; |
|
260 | 11 | } |
|
261 | 11 | } |
|
262 | |||
263 | /** |
||
264 | * Helper method to set table data in table body. |
||
265 | * |
||
266 | * Sets table data according to the column specifications, if it is |
||
267 | * specified. Otherwise it sets the data as it is stored in the data array. |
||
268 | * |
||
269 | * @param mixed[] $data table cell data. |
||
270 | * @param mixed[] $columnSpecs table columns cell settings. |
||
271 | * |
||
272 | * @return void |
||
273 | */ |
||
274 | 11 | private function setTableData($data, $columnSpecs) |
|
275 | { |
||
276 | 11 | if (empty($columnSpecs)) { |
|
277 | 11 | $this->setTableDataFromData($data); |
|
278 | 11 | } else { |
|
279 | 7 | $this->setTableDataAsSpecified($data, $columnSpecs); |
|
280 | } |
||
281 | 11 | } |
|
282 | |||
283 | /** |
||
284 | * Helper method to set table data from the data array. |
||
285 | * |
||
286 | * Sets table data from the data array. |
||
287 | * |
||
288 | * @param mixed[] $data table cell data. |
||
289 | * |
||
290 | * @return void |
||
291 | */ |
||
292 | 11 | private function setTableDataFromData($data) |
|
293 | { |
||
294 | 11 | foreach ($data as $row) { |
|
295 | 4 | $this->tableBody .= "\n<tr>"; |
|
296 | 4 | foreach ($row as $value) { |
|
297 | 4 | $this->tableBody .= "\n<td>"; |
|
298 | 4 | $this->tableBody .= htmlentities($value, null, 'UTF-8'); |
|
299 | 4 | $this->tableBody .= "</td>"; |
|
300 | 4 | } |
|
301 | 4 | $this->tableBody .= "\n</tr>"; |
|
302 | 11 | } |
|
303 | 11 | } |
|
304 | |||
305 | /** |
||
306 | * Helper method to set table data according to the column specifications. |
||
307 | * |
||
308 | * Sets the table data according to the column specifications, if the cell |
||
309 | * does not belong to the footer. Adds a colspan tag, if it is specified |
||
310 | * for the cell in the column. |
||
311 | * |
||
312 | * @param mixed[] $data table cell data. |
||
313 | * @param mixed[] $columnSpecs table columns cell settings. |
||
314 | * |
||
315 | * @return void |
||
316 | */ |
||
317 | 7 | private function setTableDataAsSpecified($data, $columnSpecs) |
|
318 | { |
||
319 | 7 | foreach ($data as $row) { |
|
320 | 7 | $this->tableBody .= "\n<tr>"; |
|
321 | 7 | foreach ($columnSpecs as $key => $columnSpec) { |
|
322 | 7 | View Code Duplication | if (!$this->isTableFooter($columnSpec)) { |
0 ignored issues
–
show
|
|||
323 | 7 | $colspan = $this->getColspan($columnSpec); |
|
324 | 7 | $this->tableBody .= "\n<td{$colspan}>"; |
|
325 | 7 | $this->tableBody .= $this->getValue($row, $key, $columnSpec); |
|
326 | 7 | $this->tableBody .= "</td>"; |
|
327 | 7 | } |
|
328 | 7 | } |
|
329 | 7 | $this->tableBody .= "\n</tr>"; |
|
330 | 7 | } |
|
331 | 7 | } |
|
332 | |||
333 | /** |
||
334 | * Helper method to get the colspan value, if specified in the column |
||
335 | * specification for the cell. |
||
336 | * |
||
337 | * @param mixed[] $columnSpec cell settings for one column. |
||
338 | * |
||
339 | * @return int the colspan value if specified. Otherwise null. |
||
340 | */ |
||
341 | 7 | private function getColspan($columnSpec) |
|
342 | { |
||
343 | 7 | return isset($columnSpec['colspan']) ? " colspan='{$columnSpec['colspan']}'" : null; |
|
344 | } |
||
345 | |||
346 | /** |
||
347 | * Helper method to get the value for a specific position in one row in |
||
348 | * the data array. |
||
349 | * |
||
350 | * Gets the data from a specific position in one row in the data array. |
||
351 | * If a function is specified for the cell in the column, the data is |
||
352 | * runned through the function before it is returned.If the object key is |
||
353 | * specified to object, the reference to the object is fetched from the |
||
354 | * array of objects. |
||
355 | * |
||
356 | * @param object $row one row of in the array of table data. |
||
357 | * @param string $key the name of the key in the associative data array. |
||
358 | * @param mixed[] $columnSpec cell settings for one column. |
||
359 | */ |
||
360 | 7 | private function getValue($row, $key, $columnSpec) |
|
361 | { |
||
362 | 7 | if ($this->isFunctionSpecified($columnSpec)) { |
|
363 | 3 | if ($this->isObjectSpecifiedAsKey($key)) { |
|
364 | 1 | $dataValue = isset($row) ? $row : ""; |
|
365 | 1 | } else { |
|
366 | 2 | $dataValue = isset($row->$key) ? $row->$key : ""; |
|
367 | } |
||
368 | |||
369 | 3 | return $this->getValueThroughFunction($columnSpec, $dataValue); |
|
370 | } else { |
||
371 | 7 | return isset($row->$key) ? htmlentities($row->$key, null, 'UTF-8') : ""; |
|
372 | } |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * Helper method t check if the function tag is specified for the cells in |
||
377 | * one column. |
||
378 | * |
||
379 | * Checks if the function tag is set for the cell in one column. |
||
380 | * |
||
381 | * @param mixed[] $columnSpec cell settings for one column. |
||
382 | * |
||
383 | * @return boolean true if a function is connected to the cell, false otherwise. |
||
384 | */ |
||
385 | 7 | private function isFunctionSpecified($columnSpec) |
|
386 | { |
||
387 | 7 | return isset($columnSpec['function']) ? true : false; |
|
388 | } |
||
389 | |||
390 | /** |
||
391 | * Helper method to check if the object key is specified to object. |
||
392 | * |
||
393 | * Checks if the object key starts with object. The check is case insensitive. |
||
394 | * |
||
395 | * @param string $key the name of the key for the object. |
||
396 | * |
||
397 | * @return boolean true if the key starts with object, false otherwise. |
||
398 | */ |
||
399 | 3 | private function isObjectSpecifiedAsKey($key) |
|
400 | { |
||
401 | 3 | $keyRest = substr($key, 0, 6); |
|
402 | |||
403 | 3 | return strcasecmp($keyRest, "object") === 0 ? true : false; |
|
404 | } |
||
405 | |||
406 | /** |
||
407 | * Helper method to run the value through a function before it is returned. |
||
408 | * |
||
409 | * Runs the value through a function, if a function is connected to the cell |
||
410 | * in the column. If not function is connected to the cell through the |
||
411 | * column specification, the value is returned as it is. |
||
412 | * |
||
413 | * WHEN USING A FUNCTION, NO DATA IS CHECKED. TO BE PROTECTED AGAINST |
||
414 | * HARMFUL DATA, THE PROTECTION MUST BE ADDED WHEN THE FUNCTION IS SPECIFIED |
||
415 | * WHEN CREATING THE TABLE! |
||
416 | * |
||
417 | * @param mixed[] $columnSpec cell settings for one column |
||
418 | * @param mixed $dataValue the value to run through function, if specified. |
||
419 | * |
||
420 | * @return the value. |
||
421 | */ |
||
422 | 3 | private function getValueThroughFunction($columnSpec, $dataValue) |
|
423 | { |
||
424 | 3 | if (!empty($columnSpec['function'])) { |
|
425 | 2 | return call_user_func($columnSpec['function'], $dataValue); |
|
426 | } else { |
||
427 | 1 | return $dataValue; |
|
428 | } |
||
429 | } |
||
430 | |||
431 | /** |
||
432 | * Helper method to create table footer with data. |
||
433 | * |
||
434 | * Creates table footer if the cell settings for the column is set to |
||
435 | * footer in the column specifications. |
||
436 | * Adds a colspan tag, if it is specified for the cell in the column. |
||
437 | * |
||
438 | * @param mixed[] $columnSpecs table columns cell settings. |
||
439 | * |
||
440 | * @return void |
||
441 | */ |
||
442 | 11 | private function createTableFooter($columnSpecs) |
|
443 | { |
||
444 | 11 | foreach ($columnSpecs as $columnSpec) { |
|
445 | 7 | View Code Duplication | if ($this->isTableFooter($columnSpec)) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
446 | 2 | $colspan = $this->getColspan($columnSpec); |
|
447 | 2 | $this->tableFoot .= "\n<td{$colspan}>"; |
|
448 | 2 | $this->tableFoot .= $this->getFooterData($columnSpec); |
|
449 | 2 | $this->tableFoot .= "</td>"; |
|
450 | 2 | } |
|
451 | 11 | } |
|
452 | |||
453 | 11 | if (isset($this->tableFoot)) { |
|
454 | 2 | $this->tableFoot = "\n<tfoot>\n<tr>" . $this->tableFoot . "\n</tr>\n</tfoot>"; |
|
455 | 2 | } |
|
456 | 11 | } |
|
457 | |||
458 | /** |
||
459 | * Helper method to get table footer data. |
||
460 | * |
||
461 | * Gets table footer data from the column specification. Checks if the |
||
462 | * value should be fetched from a function or from the value tag. |
||
463 | * If either the function or the value specified, an empty string is |
||
464 | * returned. |
||
465 | * |
||
466 | * @param mixed[] $columnSpec cell settings for one column. |
||
467 | * |
||
468 | * @return mixed the cell data value. |
||
469 | */ |
||
470 | 2 | private function getFooterData($columnSpec) |
|
471 | { |
||
472 | 2 | if ($this->isFunctionSpecified($columnSpec)) { |
|
473 | 1 | return call_user_func($columnSpec['function']); |
|
474 | } else { |
||
475 | 1 | return isset($columnSpec['value']) ? $columnSpec['value'] : ""; |
|
476 | } |
||
477 | } |
||
478 | |||
479 | /** |
||
480 | * Gets the table. |
||
481 | * |
||
482 | * Gets the table with table data. |
||
483 | * |
||
484 | * @return html the table with table data. |
||
485 | */ |
||
486 | 11 | public function getHTMLTable() |
|
487 | { |
||
488 | 11 | $id = isset($this->tableSpec['id']) ? " id='{$this->tableSpec['id']}'" : null; |
|
489 | 11 | $class = isset($this->tableSpec['class']) ? " class='{$this->tableSpec['class']}'" : null; |
|
490 | 11 | $caption = isset($this->tableSpec['caption']) ? "<caption>{$this->tableSpec['caption']}</caption>" : null; |
|
491 | |||
492 | 11 | $htmlTable = "<table{$id}{$class}>"; |
|
493 | 11 | $htmlTable .= $caption; |
|
494 | 11 | $htmlTable .= $this->tableHead; |
|
495 | 11 | $htmlTable .= $this->tableBody; |
|
496 | 11 | $htmlTable .= $this->tableFoot; |
|
497 | 11 | $htmlTable .= "\n</table>"; |
|
498 | |||
499 | 11 | return $htmlTable; |
|
500 | } |
||
501 | } |
||
502 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.