Skip to content

Commit a91e171

Browse files
fix(i18n): restore validation messages masked by duplicate top-level lang key [3.x] (#144)
* fix(i18n): consolidate validation messages into reusable translation keys * test(i18n): detect duplicate top-level keys in lang files PHP silently keeps only the last duplicate array key, which can mask entire blocks of translations. The previous duplicate `'validation'` key wiped out 200+ entries (including `unique_value`) and existing key-existence tests didn't catch it because none of the listed keys happened to live in the masked block. Adds a structural assertion across every `resources/lang/<locale>/*.php` file so future duplicates fail fast.
1 parent 6b36bf9 commit a91e171

2 files changed

Lines changed: 24 additions & 14 deletions

File tree

resources/lang/en/custom-fields.php

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,17 @@
353353
'parameter_missing' => 'This validation rule requires exactly :count parameter(s). Please add all required parameters.',
354354
'invalid_rule_for_field_type' => 'The selected rule is not valid for this field type.',
355355
'unique_value' => 'The value ":value" is already assigned to another record.',
356+
'min_length' => 'Minimum Length',
357+
'max_length' => 'Maximum Length',
358+
'min_value' => 'Minimum Value',
359+
'max_value' => 'Maximum Value',
360+
'min_selections' => 'Minimum Selections',
361+
'max_selections' => 'Maximum Selections',
362+
'max_file_size_kb' => 'Maximum File Size (KB)',
363+
'accepted_file_types' => 'Accepted File Types',
364+
'accepted_file_types_placeholder' => 'e.g. image/png, application/pdf',
365+
'decimal_places' => 'Decimal Places',
366+
'decimal_places_placeholder' => 'Enter a value between 0 and 4',
356367
],
357368

358369
'empty_states' => [
@@ -541,20 +552,6 @@
541552
'tags_input' => 'Tags Input',
542553
],
543554

544-
'validation' => [
545-
'min_length' => 'Minimum Length',
546-
'max_length' => 'Maximum Length',
547-
'min_value' => 'Minimum Value',
548-
'max_value' => 'Maximum Value',
549-
'min_selections' => 'Minimum Selections',
550-
'max_selections' => 'Maximum Selections',
551-
'max_file_size_kb' => 'Maximum File Size (KB)',
552-
'accepted_file_types' => 'Accepted File Types',
553-
'accepted_file_types_placeholder' => 'e.g. image/png, application/pdf',
554-
'decimal_places' => 'Decimal Places',
555-
'decimal_places_placeholder' => 'Enter a value between 0 and 4',
556-
],
557-
558555
'currency' => [
559556
'fieldset' => 'Currency Settings',
560557
'currency' => 'Currency',

tests/Feature/Translations/LanguageKeysTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,16 @@
9898
'field.form.description_position_options.below',
9999
'field.form.description_position_options.above',
100100
]);
101+
102+
it('has no duplicate top-level keys in any language file (PHP silently drops earlier definitions)', function (string $path): void {
103+
$contents = file_get_contents($path);
104+
preg_match_all("/^ '([^']+)' =>/m", $contents, $matches);
105+
106+
$duplicates = array_filter(array_count_values($matches[1]), fn (int $count): bool => $count > 1);
107+
108+
expect($duplicates)->toBe([], sprintf(
109+
'Duplicate top-level key(s) in %s: %s. PHP keeps only the last definition, masking earlier values.',
110+
basename(dirname($path)).'/'.basename($path),
111+
implode(', ', array_keys($duplicates)),
112+
));
113+
})->with(fn () => glob(__DIR__.'/../../../resources/lang/*/*.php'));

0 commit comments

Comments
 (0)