Explorar o código

Fix translating rules with translation engines that don't return arrays. (#826)

* translating validation rules no longer relies on the translator returning arrays for rules that apply to multiple types

* Added test for translator without array support.

---------

Co-authored-by: Bart Hijmans <bart.hijmans@dongit.eu>
bjhijmans hai 1 ano
pai
achega
90caff1f83

+ 13 - 3
src/Extracting/ParsesValidationRules.php

@@ -778,11 +778,21 @@ trait ParsesValidationRules
             return "Must match the regex {$arguments[':regex']}.";
         }
 
-        $description = trans("validation.{$rule}");
-        // For rules that can apply to multiple types (eg 'max' rule), Laravel returns an array of possible messages
+        $translationString = "validation.{$rule}";
+        $description = trans($translationString);
+
+        // For rules that can apply to multiple types (eg 'max' rule), There is an array of possible messages
         // 'numeric' => 'The :attribute must not be greater than :max'
         // 'file' => 'The :attribute must have a size less than :max kilobytes'
-        if (is_array($description)) {
+        // Depending on the translation engine, trans may return the array, or it will fail to translate the string
+        // and will need to be called with the baseType appended.
+        if ($description === $translationString) {
+            $translationString = "{$translationString}.{$baseType}";
+            $translated = trans($translationString);
+            if ($translated !== $translationString) {
+                $description = $translated;
+            }
+        } elseif (is_array($description)) {
             $description = $description[$baseType];
         }
 

+ 39 - 0
tests/Unit/ValidationRuleParsingTest.php

@@ -4,6 +4,7 @@ namespace Knuckles\Scribe\Tests\Unit;
 
 use Illuminate\Foundation\Application;
 use Illuminate\Support\Facades\Validator;
+use Illuminate\Translation\Translator;
 use Illuminate\Validation\Rule;
 use Illuminate\Validation\ValidationException;
 use Knuckles\Scribe\Extracting\ParsesValidationRules;
@@ -597,6 +598,32 @@ class ValidationRuleParsingTest extends BaseLaravelTest
             array_map(fn ($case) => $case->value, Fixtures\TestStringBackedEnum::cases())
         ));
     }
+
+    /** @test */
+    public function can_translate_validation_rules_with_types_with_translator_without_array_support()
+    {
+        // Single line DocComment
+        $ruleset = [
+            'nested' => [
+                'string', 'max:20',
+            ],
+        ];
+
+        $results = $this->strategy->parse($ruleset);
+
+        $this->assertEquals('Must not be greater than 20 characters.', $results['nested']['description']);
+
+        $this->app->extend('translator', function ($command, $app) {
+            $loader = $app['translation.loader'];
+            $locale = $app['config']['app.locale'];
+            return new DummyTranslator($loader, $locale);
+        });
+
+        $results = $this->strategy->parse($ruleset);
+
+        $this->assertEquals('successfully translated by concatenated string.', $results['nested']['description']);
+
+    }
 }
 
 class DummyValidationRule implements \Illuminate\Contracts\Validation\Rule
@@ -673,3 +700,15 @@ if ($laravel10Rules) {
         }
     }
 }
+
+class DummyTranslator extends Translator
+{
+    public function get($key, array $replace = [], $locale = null, $fallback = true)
+    {
+        if ($key === 'validation.max.string') {
+            return 'successfully translated by concatenated string';
+        }
+
+        return $key;
+    }
+}