在 Laravel 6、Module 中,自定义验证规则的 message 中翻译不可用的排查(延迟提供者的使用导致)
1、参考:https://www.shuijingwanwq.com/2022/04/26/6341/
2、在一段时间后,突然发现自定义验证规则的 message 中翻译不可用。验证失败时响应的 message 未被翻译。如图1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | { "errors": [ { "message": "Validation failed for the field [onlineStoreThemeEditorSessionDelete].", "extensions": { "validation": { "sessionId": [ "online_store_theme_graphql::validation.custom.theme_editor_session.theme_editor_session_id_exists_rule" ] }, "category": "validation" }, "locations": [ { "line": 3, "column": 3 } ], "path": [ "onlineStoreThemeEditorSessionDelete" ], "trace": ... } ], "data": { "onlineStoreThemeEditorSessionDelete": null } } |
3、参考:https://www.shuijingwanwq.com/2022/06/29/6707/ ,当删除 implements DeferrableProvider 后,再清空目录:/bootstrap/cache 后,翻译正常工作。如图2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | { "errors": [ { "message": "Validation failed for the field [onlineStoreThemeEditorSessionDelete].", "extensions": { "validation": { "sessionId": [ "The selected session id is invalid." ] }, "category": "validation" }, "locations": [ { "line": 3, "column": 3 } ], "path": [ "onlineStoreThemeEditorSessionDelete" ], "trace": ... } ], "data": { "onlineStoreThemeEditorSessionDelete": null } } |
4、在模块的服务提供者中的现有实现如下
1 2 3 4 5 6 7 8 9 10 11 12 | class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider { /** * @return void */ public function register() { $this ->registerTranslations(); // ... } } |
5、参考:/vendor/laravel/framework/src/Illuminate/Translation/TranslationServiceProvider.php ,代码调整如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider { /** * @return void */ public function register() { $this ->registerLoader(); $this ->app->singleton( 'translator' , function ( $app ) { $loader = $app [ 'translation.loader' ]; // When registering the translator component, we'll need to set the default // locale as well as the fallback locale. So, we'll grab the application // configuration so we can easily get both of these values from there. $locale = $app [ 'config' ][ 'app.locale' ]; $trans = new Translator( $loader , $locale ); $trans ->setFallback( $app [ 'config' ][ 'app.fallback_locale' ]); return $trans ; }); $this ->registerTranslations(); // ... } /** * Register the translation line loader. * * @return void */ protected function registerLoader() { $this ->app->singleton( 'translation.loader' , function ( $app ) { return new FileLoader( $app [ 'files' ], $app [ 'path.lang' ]); }); } /** * Register translations. * * @return void */ public function registerTranslations() { $langPath = resource_path( 'lang/modules/' . $this ->moduleNameLower); if ( is_dir ( $langPath )) { $this ->loadTranslationsFrom( $langPath , $this ->moduleNameLower); } else { $this ->loadTranslationsFrom(__DIR__ . '/../Resources/lang' , $this ->moduleNameLower); } } /** * 获取由提供者提供的服务。 * * @return array */ public function provides() { return [ 'translator' , 'translation.loader' ]; } } |
6、翻译正常运行。但是这样的话,感觉代码冗余得厉害。决定再次调整一下,将延迟加载的服务单独剥离出一个类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class OnlineStoreThemeGraphQLServiceProvider extends ServiceProvider { private $moduleNameLower = 'online_store_theme_graphql' ; /** * @return void */ public function register() { $this ->app->register(ResolverServiceProvider:: class ); $this ->registerTranslations(); } /** * Register translations. * * @return void */ public function registerTranslations() { $langPath = resource_path( 'lang/modules/' . $this ->moduleNameLower); if ( is_dir ( $langPath )) { $this ->loadTranslationsFrom( $langPath , $this ->moduleNameLower); } else { $this ->loadTranslationsFrom(__DIR__ . '/../Resources/lang' , $this ->moduleNameLower); } } /** * 获取由提供者提供的服务。 * * @return array */ public function provides() { return []; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class ResolverServiceProvider extends ServiceProvider implements DeferrableProvider { /** * Register the service provider. * * @return void */ public function register() { $this ->app->singleton(SettingPersistenceInterface:: class , function ( $app ){ return new DbSettingPersister(); }); $this ->app->singleton(ThemeAssetRepositoryInterface:: class , function ( $app ){ return new ThemeAssetRepository(); }); } /** * Get the services provided by the provider. * * @return array */ public function provides() { return [SettingPersistenceInterface:: class , ThemeAssetRepositoryInterface:: class ]; } } |
7、翻译正常工作。如图3
近期评论