Lines
94.44%
34 / 36
Methods
75.00%
3 / 4
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| getReportingData | 100.00% | 23 / 23 | 100.00% | 1 / 1 | 8 | ||
| convertEncoding | 77.77% | 7 / 9 | 0.00% | 0 / 1 | 5.27 | ||
| sanitize | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 2 | ||
| 31 | readonly class Report | |
| 32 | { | |
| 33 | private ReportRepository $reportRepository; | |
| 34 | ||
| 35 | /** | |
| 36 | * Constructor. | |
| 37 | */ | |
| 38 | public function __construct(Configuration $configuration) | |
| 39 | { | |
| 40 | $this->reportRepository = new ReportRepository($configuration); | |
| 41 | } | |
| 42 | ||
| 43 | /** | |
| 44 | * Generates a huge array for the report. | |
| 45 | * | |
| 46 | * @return array<int, array<string, mixed>> | |
| 47 | */ | |
| 48 | public function getReportingData(): array | |
| 49 | { | |
| 50 | $report = []; | |
| 51 | $rows = $this->reportRepository->fetchAllReportData(); | |
| 52 | ||
| 53 | $lastId = 0; | |
| 54 | foreach ($rows as $row) { | |
| 55 | $rowId = (int) $row->id; | |
| 56 | if ($rowId === $lastId) { | |
| 57 | ++$report[$rowId]['faq_translations']; | |
| 58 | } | |
| 59 | ||
| 60 | $report[$rowId] = [ | |
| 61 | 'faq_id' => (int) $row->id, | |
| 62 | 'faq_language' => (string) $row->lang, | |
| 63 | 'category_id' => $row->category_id === null ? null : (int) $row->category_id, | |
| 64 | 'category_parent' => $row->parent_id === null ? null : (int) $row->parent_id, | |
| 65 | 'category_name' => $row->category_name === null ? null : (string) $row->category_name, | |
| 66 | 'faq_translations' => 0, | |
| 67 | 'faq_sticky' => (int) $row->sticky, | |
| 68 | 'faq_question' => (string) $row->question, | |
| 69 | 'faq_org_author' => (string) $row->original_author, | |
| 70 | 'faq_updated' => Date::createIsoDate((string) $row->updated), | |
| 71 | 'faq_visits' => $row->visits === null ? null : (int) $row->visits, | |
| 72 | 'faq_last_author' => $row->last_author === null ? null : (string) $row->last_author, | |
| 73 | ]; | |
| 74 | ||
| 75 | $lastId = $rowId; | |
| 76 | } | |
| 77 | ||
| 78 | return $report; | |
| 79 | } | |
| 80 | ||
| 81 | /** | |
| 82 | * Convert string to the correct encoding and removes possible | |
| 83 | * bad strings to avoid formula injection attacks. | |
| 84 | * | |
| 85 | * @param string $outputString String to encode. | |
| 86 | * @return string Encoded string. | |
| 87 | */ | |
| 88 | public function convertEncoding(string $outputString = ''): string | |
| 89 | { | |
| 90 | $outputString = html_entity_decode($outputString, ENT_QUOTES, encoding: 'utf-8'); | |
| 91 | $outputString = str_replace(search: ',', replace: ' ', subject: $outputString); | |
| 92 | ||
| 93 | if (extension_loaded(extension: 'mbstring')) { | |
| 94 | $detected = mb_detect_encoding($outputString); | |
| 95 | ||
| 96 | if ($detected !== false && $detected !== 'ASCII') { | |
| 97 | $converted = mb_convert_encoding($outputString, to_encoding: 'UTF-16', from_encoding: $detected); | |
| 98 | $outputString = is_string($converted) ? $converted : $outputString; | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | $toBeRemoved = ['=', '+', '-', 'HYPERLINK']; | |
| 103 | return str_replace(search: $toBeRemoved, replace: '', subject: $outputString); | |
| 104 | } | |
| 105 | ||
| 106 | /** | |
| 107 | * Sanitizes input to avoid CSV injection. | |
| 108 | */ | |
| 109 | public static function sanitize(int|string $value): string|int | |
| 110 | { | |
| 111 | if (preg_match(pattern: '/[=\+\-\@\|]/', subject: (string) $value)) { | |
| 112 | return '"' . str_replace(search: '"', replace: '""', subject: (string) $value) . '"'; | |
| 113 | } | |
| 114 | ||
| 115 | return $value; | |
| 116 | } | |
| 117 | } |