Skip to content

Commit 2e3d125

Browse files
authored
Merge branch 'develop' into feature/126-implement-peppol
2 parents ec5f51a + 1f0e1a3 commit 2e3d125

File tree

2 files changed

+99
-100
lines changed

2 files changed

+99
-100
lines changed

.github/scripts/parse-phpstan-results.php

Lines changed: 58 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
<?php
33

44
/**
5-
* PHPStan Results Parser.
65
*
76
* This script parses PHPStan JSON output and generates a formatted, actionable report.
87
* It groups errors by class, strips noise, and generates a markdown checklist suitable
@@ -17,21 +16,21 @@
1716

1817
$jsonFile = $argv[1];
1918

20-
if ( ! file_exists($jsonFile)) {
21-
echo "Error: File '{$jsonFile}' not found.\n";
19+
if (!file_exists($jsonFile)) {
20+
echo "Error: File '$jsonFile' not found.\n";
2221
exit(1);
2322
}
2423

2524
$content = file_get_contents($jsonFile);
26-
$data = json_decode($content, true);
25+
$data = json_decode($content, true);
2726

2827
if (json_last_error() !== JSON_ERROR_NONE) {
29-
echo "Error: Invalid JSON in '{$jsonFile}': " . json_last_error_msg() . "\n";
28+
echo "Error: Invalid JSON in '$jsonFile': " . json_last_error_msg() . "\n";
3029
exit(1);
3130
}
3231

3332
// Extract errors from PHPStan JSON format
34-
$files = $data['files'] ?? [];
33+
$files = $data['files'] ?? [];
3534
$totalErrors = $data['totals']['file_errors'] ?? 0;
3635

3736
if ($totalErrors === 0) {
@@ -41,42 +40,42 @@
4140
}
4241

4342
// Group errors by class/file
44-
$errorsByFile = [];
43+
$errorsByFile = [];
4544
$errorsByCategory = [
46-
'type_errors' => [],
47-
'method_errors' => [],
48-
'property_errors' => [],
45+
'type_errors' => [],
46+
'method_errors' => [],
47+
'property_errors' => [],
4948
'return_type_errors' => [],
50-
'other_errors' => [],
49+
'other_errors' => [],
5150
];
5251

5352
foreach ($files as $filePath => $fileData) {
5453
$messages = $fileData['messages'] ?? [];
55-
54+
5655
foreach ($messages as $message) {
5756
$errorText = $message['message'] ?? '';
58-
$line = $message['line'] ?? 0;
59-
57+
$line = $message['line'] ?? 0;
58+
6059
// Categorize errors
6160
$category = categorizeError($errorText);
62-
61+
6362
$errorsByFile[$filePath][] = [
64-
'line' => $line,
65-
'message' => $errorText,
63+
'line' => $line,
64+
'message' => $errorText,
6665
'category' => $category,
6766
];
68-
67+
6968
$errorsByCategory[$category][] = [
70-
'file' => $filePath,
71-
'line' => $line,
69+
'file' => $filePath,
70+
'line' => $line,
7271
'message' => $errorText,
7372
];
7473
}
7574
}
7675

7776
// Generate markdown report
7877
echo "## 🔍 PHPStan Analysis Report\n\n";
79-
echo "**Total Errors:** {$totalErrors}\n\n";
78+
echo "**Total Errors:** $totalErrors\n\n";
8079

8180
// Summary by category
8281
echo "### 📊 Error Summary by Category\n\n";
@@ -85,7 +84,7 @@
8584
if ($count > 0) {
8685
$emoji = getCategoryEmoji($category);
8786
$label = getCategoryLabel($category);
88-
echo "- {$emoji} **{$label}**: {$count} error(s)\n";
87+
echo "- $emoji **$label**: $count error(s)\n";
8988
}
9089
}
9190
echo "\n---\n\n";
@@ -96,19 +95,19 @@
9695
$fileCount = 0;
9796
foreach ($errorsByFile as $filePath => $errors) {
9897
$fileCount++;
99-
$shortPath = getShortPath($filePath);
98+
$shortPath = getShortPath($filePath);
10099
$errorCount = count($errors);
101-
102-
echo "#### {$fileCount}. `{$shortPath}` ({$errorCount} error(s))\n\n";
103-
100+
101+
echo "#### $fileCount. `$shortPath` ($errorCount error(s))\n\n";
102+
104103
foreach ($errors as $error) {
105-
$line = $error['line'];
106-
$message = trimMessage($error['message']);
104+
$line = $error['line'];
105+
$message = trimMessage($error['message']);
107106
$category = getCategoryLabel($error['category']);
108-
109-
echo "- **Line {$line}** [{$category}]: {$message}\n";
107+
108+
echo "- **Line $line** [$category]: $message\n";
110109
}
111-
110+
112111
echo "\n";
113112
}
114113

@@ -120,23 +119,23 @@
120119

121120
foreach ($errorsByFile as $filePath => $errors) {
122121
$shortPath = getShortPath($filePath);
123-
122+
124123
foreach ($errors as $error) {
125-
$line = $error['line'];
124+
$line = $error['line'];
126125
$message = trimMessage($error['message'], 80);
127-
128-
echo "- [ ] Fix error in `{$shortPath}:{$line}` - {$message}\n";
126+
127+
echo "- [ ] Fix error in `$shortPath:$line` - $message\n";
129128
}
130129
}
131130

132131
echo "\n---\n";
133132

134133
/**
135-
* Categorize error based on message content.
134+
* Categorize error based on message content
136135
*/
137136
function categorizeError(string $message): string
138137
{
139-
$normalizedMessage = mb_strtolower($message);
138+
$normalizedMessage = strtolower($message);
140139

141140
$hasShouldReturn = str_contains($normalizedMessage, 'should return');
142141
$hasMethod = str_contains($normalizedMessage, 'method');
@@ -164,44 +163,44 @@ function categorizeError(string $message): string
164163
if (($hasType || $hasExpects) && ! $hasMethod && ! $hasCallTo && ! $hasProperty) {
165164
return 'type_errors';
166165
}
167-
166+
168167
return 'other_errors';
169168
}
170169

171170
/**
172-
* Get emoji for error category.
171+
* Get emoji for error category
173172
*/
174173
function getCategoryEmoji(string $category): string
175174
{
176175
$emojis = [
177-
'type_errors' => '🔢',
178-
'method_errors' => '🔧',
179-
'property_errors' => '📦',
176+
'type_errors' => '🔢',
177+
'method_errors' => '🔧',
178+
'property_errors' => '📦',
180179
'return_type_errors' => '↩️',
181-
'other_errors' => '⚠️',
180+
'other_errors' => '⚠️',
182181
];
183-
182+
184183
return $emojis[$category] ?? '';
185184
}
186185

187186
/**
188-
* Get human-readable label for category.
187+
* Get human-readable label for category
189188
*/
190189
function getCategoryLabel(string $category): string
191190
{
192191
$labels = [
193-
'type_errors' => 'Type Errors',
194-
'method_errors' => 'Method Errors',
195-
'property_errors' => 'Property Errors',
192+
'type_errors' => 'Type Errors',
193+
'method_errors' => 'Method Errors',
194+
'property_errors' => 'Property Errors',
196195
'return_type_errors' => 'Return Type Errors',
197-
'other_errors' => 'Other Errors',
196+
'other_errors' => 'Other Errors',
198197
];
199-
198+
200199
return $labels[$category] ?? 'Unknown';
201200
}
202201

203202
/**
204-
* Shorten file path for readability.
203+
* Shorten file path for readability
205204
*/
206205
function getShortPath(string $path): string
207206
{
@@ -211,39 +210,39 @@ function getShortPath(string $path): string
211210
// Derive project root based on this script's location: .github/scripts => project root is two levels up
212211
$projectRoot = dirname(__DIR__, 2);
213212
if (is_string($projectRoot) && $projectRoot !== '') {
214-
$normalizedRoot = mb_rtrim(str_replace('\\', '/', $projectRoot), '/') . '/';
213+
$normalizedRoot = rtrim(str_replace('\\', '/', $projectRoot), '/') . '/';
215214

216215
if (str_starts_with($normalizedPath, $normalizedRoot)) {
217-
$normalizedPath = mb_substr($normalizedPath, mb_strlen($normalizedRoot));
216+
$normalizedPath = substr($normalizedPath, strlen($normalizedRoot));
218217
}
219218
}
220219

221220
// Fallback: also try stripping the current working directory if it is a prefix
222221
$cwd = getcwd();
223222
if (is_string($cwd) && $cwd !== '') {
224-
$normalizedCwd = mb_rtrim(str_replace('\\', '/', $cwd), '/') . '/';
223+
$normalizedCwd = rtrim(str_replace('\\', '/', $cwd), '/') . '/';
225224

226225
if (str_starts_with($normalizedPath, $normalizedCwd)) {
227-
$normalizedPath = mb_substr($normalizedPath, mb_strlen($normalizedCwd));
226+
$normalizedPath = substr($normalizedPath, strlen($normalizedCwd));
228227
}
229228
}
230229

231230
return $normalizedPath;
232231
}
233232

234233
/**
235-
* Trim message to reasonable length.
234+
* Trim message to reasonable length
236235
*/
237236
function trimMessage(string $message, int $maxLength = 150): string
238237
{
239238
// Remove excessive whitespace
240239
$message = preg_replace('/\s+/', ' ', $message);
241-
$message = mb_trim($message);
242-
240+
$message = trim($message);
241+
243242
// Truncate if too long (multibyte-safe)
244243
if (mb_strlen($message, 'UTF-8') > $maxLength) {
245244
$message = mb_substr($message, 0, $maxLength - 3, 'UTF-8') . '...';
246245
}
247-
246+
248247
return $message;
249248
}

resources/lang/en/ip.php

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -836,9 +836,9 @@
836836
#endregion
837837

838838
#region EXPORTS
839-
'export_completed' => 'Your :entity export has completed and :count :rows exported.',
840-
'export_failed_rows' => ':count :rows failed to export.',
841-
'row' => 'row|rows',
839+
'export_completed' => 'Your :entity export has completed and :count :rows exported.',
840+
'export_failed_rows' => ':count :rows failed to export.',
841+
'row' => 'row|rows',
842842
#endregion
843843

844844
#region AUTHENTICATION
@@ -859,52 +859,52 @@
859859
#endregion
860860

861861
#region NUMBERING
862-
'numbering' => 'Numbering',
863-
'numberings' => 'Numberings',
864-
'numbering_company' => 'Company',
865-
'numbering_company_assignment' => 'Company Assignment',
866-
'numbering_select_company_help' => 'Select which company this numbering scheme belongs to',
867-
'numbering_type' => 'Type',
868-
'numbering_name' => 'Name',
869-
'numbering_next_id' => 'Next ID',
870-
'numbering_next_id_help' => 'Can be adjusted to troubleshoot numbering issues',
871-
'numbering_left_pad' => 'Left Pad',
872-
'numbering_prefix' => 'Prefix',
873-
'numbering_format' => 'Format',
874-
'numbering_format_placeholder' => '{{prefix}}-{{number}}',
875-
'numbering_format_help' => 'Use {{prefix}}, {{number}}, {{year}}, {{yy}}, {{month}}, {{day}} as placeholders. Only dash (-) or underscore (_) separators allowed.',
876-
'numbering_format_helper' => 'You can customize the format using placeholders: {{prefix}} for prefix, {{number}} for sequential number, {{year}} for 4-digit year, {{yy}} for 2-digit year, {{month}} for month, {{day}} for day. The number will be left-padded according to the Left Pad setting.',
877-
'numbering_format_helper_admin' => 'The format string can use {{prefix}} for the prefix and {{number}} for the sequential number. The number will be left-padded according to the Left Pad setting.',
878-
'numbering_format_help_label' => 'Format Help',
879-
'duplicate_invoice_number' => 'Duplicate invoice number :number for company :company',
880-
'duplicate_quote_number' => 'Duplicate quote number :number for company :company',
862+
'numbering' => 'Numbering',
863+
'numberings' => 'Numberings',
864+
'numbering_company' => 'Company',
865+
'numbering_company_assignment' => 'Company Assignment',
866+
'numbering_select_company_help' => 'Select which company this numbering scheme belongs to',
867+
'numbering_type' => 'Type',
868+
'numbering_name' => 'Name',
869+
'numbering_next_id' => 'Next ID',
870+
'numbering_next_id_help' => 'Can be adjusted to troubleshoot numbering issues',
871+
'numbering_left_pad' => 'Left Pad',
872+
'numbering_prefix' => 'Prefix',
873+
'numbering_format' => 'Format',
874+
'numbering_format_placeholder' => '{{prefix}}-{{number}}',
875+
'numbering_format_help' => 'Use {{prefix}}, {{number}}, {{year}}, {{yy}}, {{month}}, {{day}} as placeholders. Only dash (-) or underscore (_) separators allowed.',
876+
'numbering_format_helper' => 'You can customize the format using placeholders: {{prefix}} for prefix, {{number}} for sequential number, {{year}} for 4-digit year, {{yy}} for 2-digit year, {{month}} for month, {{day}} for day. The number will be left-padded according to the Left Pad setting.',
877+
'numbering_format_helper_admin' => 'The format string can use {{prefix}} for the prefix and {{number}} for the sequential number. The number will be left-padded according to the Left Pad setting.',
878+
'numbering_format_help_label' => 'Format Help',
879+
'duplicate_invoice_number' => 'Duplicate invoice number :number for company :company',
880+
'duplicate_quote_number' => 'Duplicate quote number :number for company :company',
881881
#endregion
882882

883883
#region REPORT BUILDER
884-
'template_name' => 'Template Name',
885-
'template_type' => 'Template Type',
886-
'estimate' => 'Estimate',
887-
'system_template' => 'System Template',
888-
'design' => 'Design',
889-
'clone' => 'Clone',
884+
'template_name' => 'Template Name',
885+
'template_type' => 'Template Type',
886+
'estimate' => 'Estimate',
887+
'system_template' => 'System Template',
888+
'design' => 'Design',
889+
'clone' => 'Clone',
890890
#endregion
891891

892892
#region GENERAL
893-
'format' => 'Format',
894-
'padding' => 'Padding',
895-
'system' => 'System',
896-
'created_at' => 'Created At',
897-
'customer' => 'Customer',
898-
'prospect' => 'Prospect',
899-
'partner' => 'Partner',
900-
'lead' => 'Lead',
901-
'gender_unknown' => 'Unknown',
893+
'format' => 'Format',
894+
'padding' => 'Padding',
895+
'system' => 'System',
896+
'created_at' => 'Created At',
897+
'customer' => 'Customer',
898+
'prospect' => 'Prospect',
899+
'partner' => 'Partner',
900+
'lead' => 'Lead',
901+
'gender_unknown' => 'Unknown',
902902
#endregion
903903

904904
#region TAX RATES
905-
'tax_rate_type_exclusive' => 'Exclusive',
906-
'tax_rate_type_inclusive' => 'Inclusive',
907-
'tax_rate_type_zero' => 'Zero Rated',
908-
'tax_rate_type_exempt' => 'Exempt',
905+
'tax_rate_type_exclusive' => 'Exclusive',
906+
'tax_rate_type_inclusive' => 'Inclusive',
907+
'tax_rate_type_zero' => 'Zero Rated',
908+
'tax_rate_type_exempt' => 'Exempt',
909909
#endregion
910910
];

0 commit comments

Comments
 (0)